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

React Testing Library测试Modal Portal报错:目标容器非DOM元素

解决React createPortal Modal测试时"Target container is not a DOM element"错误

问题根源

你的Modal组件依赖document.getElementById('portal')作为createPortal的目标容器,但Jest测试环境的默认DOM结构里并没有这个节点,导致渲染时找不到目标元素报错。

两种可行解决方案

方案1:测试用例中动态创建/清理portal容器

在测试执行前手动添加目标DOM节点,测试结束后移除,避免污染其他测试:

test('modal', () => {
  // 提前创建portal容器
  const portalDiv = document.createElement('div');
  portalDiv.id = 'portal';
  document.body.appendChild(portalDiv);

  const handleClose = jest.fn();
  const { getByText } = render(<Modal onClose={handleClose} isOpen title={'title'} />);
  
  expect(getByText('title')).toBeTruthy();

  // 测试完成后清理DOM
  document.body.removeChild(portalDiv);
});

方案2:让组件支持自定义portal容器(更灵活)

给Modal组件增加一个可选的portalContainer属性,允许测试时传入自定义容器,同时保留原有的默认逻辑:

// 更新组件Props定义
interface IModalProps {
  isOpen: boolean;
  title?: string;
  className?: string;
  onClose: () => void;
  content?: React.ReactNode; // 替换React.ReactChildren,ReactNode是官方推荐的可渲染内容类型
  portalContainer?: Element | null;
}

// 修改Modal组件的返回逻辑
const Modal = ({isOpen, title, content, onClose, className, portalContainer}: IModalProps) => {
  // ... 原有keydownHandler和useEffect逻辑不变

  const modalInPortal = () => (
    // ... 原有modal结构不变
  );

  // 优先使用传入的容器,否则取默认的portal节点
  const targetContainer = portalContainer || document.getElementById('portal');
  // 容错处理:如果容器不存在,返回null避免报错
  if (!targetContainer) return null;

  return createPortal(modalInPortal(), targetContainer);
};

对应的测试代码可以简化为:

test('modal', () => {
  const handleClose = jest.fn();
  const testPortal = document.createElement('div');
  
  const { getByText } = render(
    <Modal 
      onClose={handleClose} 
      isOpen 
      title={'title'} 
      portalContainer={testPortal} 
    />
  );
  
  expect(getByText('title')).toBeTruthy();
});

额外提示

组件中content的类型React.ReactChildren | React.ReactChild建议替换为React.ReactNode,这是React官方定义的涵盖所有可渲染内容(元素、文本、Fragment等)的类型,更准确且通用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:35:38