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

React Portals报错‘Target container is not a DOM element’排查求助

React Portal报错「Target container is not a DOM element」原因及解决

错误原因

  1. DOM元素未挂载就执行查找:你在ButtonsPortal组件初始化时直接调用document.getElementById('table-buttons'),此时Table组件里的目标div还没被React渲染到真实DOM中,返回结果为null,导致createPortal因接收无效容器报错。
  2. 条件渲染导致容器可能不存在:目标div仅在actionRender为true时才会渲染,若actionRender为false,该div根本不会出现在DOM中,同样会触发查找失败。

解决方法

放弃全局ID查找的方式,改用React的useRef获取目标容器的引用,并确保只有当容器存在时才渲染Portal,具体修改如下:

Table组件修改(用useRef绑定容器)

import { useRef } from 'react';

const Table = ({ showCheckbox, isIndeterminate, handleOnChange, isChecked, data, headers, actionRender }) => {
  // 创建ref指向目标容器
  const buttonsContainerRef = useRef(null);

  return (
    <tr>
      {showCheckbox &&
        <th className="checkbox-table">
          <Checkbox
            indeterminate={isIndeterminate}
            onChange={handleOnChange}
            checked={isChecked}
            disabled={data.every((row) => row.disabled)}
          />
        </th>
      }
      {headers.map((header) =>
        <th key={uid()} className="table-cell">
          {header.title}
        </th>
      )}
      {actionRender &&
        <th>
          {/* 用ref绑定目标div */}
          <div ref={buttonsContainerRef}></div>
          {/* 仅当容器存在时渲染Portal */}
          {buttonsContainerRef.current && <ButtonsPortal target={buttonsContainerRef.current} />}
        </th>
      }
    </tr>
  );
};

Portal组件修改(接收目标容器作为props)

const ButtonsPortal = ({ target }) => {
  // 目标容器不存在时返回null,避免报错
  if (!target) return null;
  return createPortal(<button>Test</button>, target);
};

方案说明

  • useRef是React官方推荐的组件内DOM元素获取方式,既避免了全局ID查找的耦合问题,又能精准定位当前组件实例内的容器。
  • 通过buttonsContainerRef.current的存在判断,确保Portal仅在目标容器挂载到DOM后才渲染,从根源上消除「容器不存在」的报错。
  • Portal组件内部的空值判断是双重保险,防止意外场景下传入无效目标。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:41:41