React 将任意 ReactNode 类型的节点在render函数外渲染到页面上

当一个 ReactNode 类型的节点,没有在 render 函数内时,如何渲染到页面上呢?

就需要借助 react-dom/client 中的 createRoot 函数,同时在不需要的时候销毁所有内容。

所以,就搞一个 hook 函数,函数加载的时候节点被 render 到页面上,函数卸载的时候卸载所有内容。同时增加当节点内容变化时更新 DOM 的功能。

tsx 复制代码
import React, { FC, useRef, useState, useEffect, type ReactNode } from 'react'
import { createRoot, type Root } from 'react-dom/client'


type useRenderDocumentProps = (renderNode: ReactNode) => void

const useRenderDocument: useRenderDocumentProps = (renderNode) => {

  const rootRef = useRef<HTMLDivElement | null>(null)
  const rootInstanceRef = useRef<Root | null>(null)

  const prevNode = useRef(renderNode)

  useEffect(() => {
    if (rootInstanceRef.current && prevNode.current !== renderNode) {
      rootInstanceRef.current.render(renderNode)
      prevNode.current = renderNode
    }
  }, [renderNode])

  useEffect(() => {

    if (!rootInstanceRef.current) {
      const root = document.createElement('div')
      root.className = 'render-root'
      document.body.appendChild(root)
      rootRef.current = root
      rootInstanceRef.current = createRoot(root)
      rootInstanceRef.current.render(renderNode)
    }
    return () => {
      console.log('销毁')
      if (rootRef.current) {
        rootRef.current.remove()
        rootRef.current = null
        rootInstanceRef.current?.unmount()
        rootInstanceRef.current = null
      }
    }
  }, [])
}

export default useRenderDocument
相关推荐
原则猫2 小时前
HOOKS 背后机制
前端
码语智行2 小时前
首页导航跳转功能深度解析-系统内和系统外
前端
阿猫的故乡3 小时前
Vue过渡动画从入门到装X:淡入淡出、滑动、列表动画、第三方库全搞定
前端·javascript·vue.js
IManiy3 小时前
总结之Vibe Coding前端骨架
前端
JS菌3 小时前
AI Agent 沙箱双层防护体系:从权限过滤到内核隔离的完整实现
前端·人工智能·后端
Aphasia3113 小时前
从输入URL到页面展示全流程
前端·面试
我叫黑大帅4 小时前
前端如何竖屏固定视口背景
前端·javascript·面试
abcy0712134 小时前
python pandas csv异步后台清洗前端优先返回成功信息
前端·python·pandas
IT_陈寒4 小时前
Vite这个坑我帮你踩了,动态导入居然这样才生效
前端·人工智能·后端
swipe4 小时前
Mem0 x Agent 实战系列:分层记忆 + 三路召回,搭建真正可用的长期记忆层
前端·javascript·面试