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
相关推荐
晴殇i14 分钟前
🎉 TRAE 一年使用的过程体验 🎉
前端
GDAL18 分钟前
Tailwind CSS Flex 布局深入全面教程
前端·css·tailwindcss
qq. 280403398421 分钟前
react --> redux
前端·react.js·前端框架
前端不太难24 分钟前
用 RN 的渲染模型,反推 Vue 列表的正确拆分方式
前端·javascript·vue.js
JS_GGbond29 分钟前
防抖与节流:前端性能优化“双剑客”
前端
KLW7533 分钟前
vue v-if和v-show比较
前端·css·css3
梵尔纳多38 分钟前
使用 Electron 实现一个简单的文本编辑器
前端·javascript·electron
晴殇i40 分钟前
SPA首屏加载速度优化!
前端
qq. 280403398441 分钟前
react 副作用探究
前端·react.js
小oo呆1 小时前
【自然语言处理与大模型】LangChainV1.0入门指南:核心组件Streaming
前端·javascript·easyui