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

非React项目中ReactDOM渲染组件移除后无法二次渲染的问题

问题解决方案

问题原因

当模态框隐藏时直接通过innerHTML = ''清空#modal_body,会绕过React的组件卸载流程,导致React内部保留着对已销毁DOM节点的引用,再次调用ReactDOM.render()时无法正确重新挂载组件。

解决方法

1. 适配React 17及以下版本的方案

修改模态框隐藏逻辑,先通过React官方API卸载组件,再执行DOM清理:

function hideModal() {
  const modalBody = document.getElementById('modal_body');
  // 先卸载React组件,确保生命周期正常执行
  ReactDOM.unmountComponentAtNode(modalBody);
  // 再执行原有隐藏逻辑
  modalBody.innerHTML = '';
  modalBody.style.display = 'none';
}

同时在打开模态框的点击事件中,提前清理残留组件,保证重新渲染的环境干净:

$(document).on("click", ".js-popup-form", function () {
  showModal();
  const modalBody = document.getElementById("modal_body");
  // 清理可能残留的组件实例
  ReactDOM.unmountComponentAtNode(modalBody);
  // 重新渲染获客表单
  ReactDOM.render(<LeadForm />, modalBody);
});

2. React 18+推荐方案(使用createRoot API)

React 18弃用了ReactDOM.render,改用createRoot管理根节点,能更稳定处理组件挂载/卸载:

// 打开模态框的点击事件
$(document).on("click", ".js-popup-form", function () {
  showModal();
  const modalBody = document.getElementById("modal_body");
  
  // 卸载旧的根实例(如果存在)
  if (modalBody._reactRoot) {
    modalBody._reactRoot.unmount();
  }
  
  // 创建新根节点并渲染表单
  const root = ReactDOM.createRoot(modalBody);
  root.render(<LeadForm />);
  
  // 保存根实例引用,方便后续卸载
  modalBody._reactRoot = root;
});

// 隐藏模态框的函数
function hideModal() {
  const modalBody = document.getElementById('modal_body');
  
  // 卸载React根实例
  if (modalBody._reactRoot) {
    modalBody._reactRoot.unmount();
    delete modalBody._reactRoot;
  }
  
  // 执行原有隐藏逻辑
  modalBody.innerHTML = '';
  modalBody.style.display = 'none';
}

核心思路

必须通过React提供的API管理组件的挂载与卸载,避免直接操作DOM修改React渲染的内容,确保React内部状态与实际DOM保持一致,就能解决重复打开模态框时组件无法重新渲染的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:45:29