You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何将getElementById替换为useRef避免useEffect内调用报错

报错原因

React Hook 有强制调用规则:必须在React函数组件的最顶层调用,不能嵌套在useEffect、循环、条件判断、普通回调函数内部,你之前把useRef写在useEffect回调里,自然会触发规则校验报错。

分场景实现方案

场景1:createPortal的挂载节点是当前组件内部渲染的元素

这是最推荐的React原生实现,完全不需要手动操作原生DOM:

import { useRef, useEffect, useState } from 'react'
import { createPortal } from 'react-dom'

function MyComponent() {
  // 组件最顶层声明ref,初始值设为null
  const portalContainerRef = useRef<HTMLOListElement>(null)
  const [portalContent, setPortalContent] = useState<React.ReactNode>(null)

  // 组件挂载完成、ref已经绑定到真实DOM后再创建portal
  useEffect(() => {
    if (portalContainerRef.current) {
      setPortalContent(<div>portal渲染的内容</div>)
    }
  }, [])

  return (
    <div>
      {/* 把ref绑定到你要作为挂载容器的对应元素上 */}
      <ol ref={portalContainerRef} />
      {/* 确认ref存在真实DOM节点后再渲染portal */}
      {portalContent && createPortal(portalContent, portalContainerRef.current)}
    </div>
  )
}

场景2:createPortal的挂载节点是当前组件外部的DOM(比如页面提前写死的公共容器)

这种场景可以用useRef存储查询到的DOM引用,避免每次渲染都重复查询DOM:

import { useRef, useEffect, useState } from 'react'
import { createPortal } from 'react-dom'

const MY_PORTAL_CONTAINER_ID = 'myDefaultElement'

function MyComponent() {
  // 组件最顶层声明ref,用来存储外部DOM的引用
  const portalContainerRef = useRef<HTMLOListElement | null>(null)
  const [portalContent, setPortalContent] = useState<React.ReactNode>(null)

  useEffect(() => {
    // 组件挂载时查询外部DOM,赋值给ref的current属性
    portalContainerRef.current = document.getElementById(MY_PORTAL_CONTAINER_ID) as HTMLOListElement | null
    if (portalContainerRef.current) {
      setPortalContent(<div>portal渲染的内容</div>)
    }

    // 组件卸载时如果需要清理容器内容可补充对应逻辑
    return () => {
      if (portalContainerRef.current) {
        portalContainerRef.current.innerHTML = ''
      }
    }
  }, [])

  return portalContent && portalContainerRef.current 
    ? createPortal(portalContent, portalContainerRef.current) 
    : null
}

注意:如果外部容器可能被其他逻辑删除,建议补充DOM存在性判断,避免访问不存在的节点报错。

内容的提问来源于stack exchange,提问作者Leo Messi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 12:15:00