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
相关产品推荐
相关产品推荐

