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

React/JavaScript替换div内容:点击按钮切换组件并清空旧内容

解决React Portal无法清除原有内容的组件替换问题

核心问题在于你每次调用ReactDOM.createPortal时,只是向目标div追加内容,没有让React接管该div的内容更新逻辑。正确的做法是通过React状态控制要渲染的组件,让React自动处理旧内容的卸载和新内容的挂载。

推荐实现方案

通过维护一个状态变量,控制Portal中渲染的组件。当状态变化时,React会自动卸载旧组件(清空#test的原有内容),并渲染新组件,完全匹配你的需求:

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

// 你的A、B组件
const A = () => <div>A组件内容</div>;
const B = () => <div>B组件内容</div>;

const App = () => {
  // 维护当前要渲染的组件状态
  const [currentComponent, setCurrentComponent] = useState(null);
  // 获取目标div容器
  const targetContainer = document.getElementById('test');

  return (
    <div>
      <button onClick={() => setCurrentComponent(<A />)}>A1</button>
      <button onClick={() => setCurrentComponent(<B />)}>B1</button>
      {/* 仅当目标容器存在时渲染Portal */}
      {targetContainer && ReactDOM.createPortal(currentComponent, targetContainer)}
    </div>
  );
};

// 渲染主应用
ReactDOM.render(<App />, document.getElementById('root'));

方案生效原因

React会跟踪Portal内的组件状态变化:

  • 点击按钮时,状态currentComponent更新为新的组件实例
  • React自动卸载之前渲染在Portal中的旧组件(清空#test内容)
  • 随后挂载新组件到目标div,全程由React管理DOM,避免手动操作的风险

不推荐的手动清理方式

如果你一定要手动清空目标div再插入内容,可以这么写,但不建议——这会绕过React的DOM管理机制,可能导致旧组件的生命周期方法(比如componentWillUnmount)无法执行,引发内存泄漏:

const handleClickA = () => {
  const testDiv = document.getElementById('test');
  // 手动清空原有内容
  testDiv.innerHTML = '';
  // 创建新的Portal
  ReactDOM.createPortal(<A />, testDiv);
};

内容的提问来源于stack exchange,提问作者Łukasz Maśliński

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:40:34