React应用程序化重启后出现双渲染问题,如何修复?
问题:React应用程序化重启后出现双渲染问题
开发React Web应用时,需在更新设置后通过程序化方式重启应用(不刷新页面),当前实现代码如下:
class App { destroy() { // rootDom 是<AppComponent />的挂载节点 ReactDOM.unmountComponentAtNode(this.rootDom); this.rootDom?.remove(); this.addons = {} as any; delete App.instances[this.appName]; } async restart() { this.destroy(); await this.ready(); await this.start(); } }
执行代码后表面功能正常,但滚动页面时出现双渲染现象(页面滚动时可见两层重复的内容)。
修复方案
1. 彻底清理挂载节点内容,避免残留
当前destroy方法中直接删除rootDom,若start方法重启时又在同一父容器下创建新的挂载节点,就会导致新旧节点共存。修改destroy逻辑,改为清空节点内容而非删除节点本身:
destroy() { // 先卸载组件 ReactDOM.unmountComponentAtNode(this.rootDom); // 清空rootDom内所有子元素,保留节点本身用于复用 while (this.rootDom.firstChild) { this.rootDom.removeChild(this.rootDom.firstChild); } this.addons = {} as any; delete App.instances[this.appName]; }
2. 检查start方法是否重复创建挂载节点
确认start方法中是复用已清空的rootDom,而非每次重启都新建div并插入到父容器。如果重复创建节点,旧节点未被彻底清理就会和新节点并存,引发双渲染。
3. 确保异步流程中挂载时机正确
restart里的await ready()和await start()需保证destroy完全执行完毕后再进行新组件挂载。检查ready方法是否存在可能导致节点重复初始化的逻辑,确保新挂载只在清理后的rootDom上执行。
4. React 18环境下改用新卸载API
若使用React 18,ReactDOM.unmountComponentAtNode已过时,建议用createRoot创建的实例调用unmount,卸载更彻底:
// 初始化环节保存root实例 this.root = ReactDOM.createRoot(this.rootDom); this.root.render(<AppComponent />); // 销毁方法修改为 destroy() { this.root.unmount(); // 清空节点内容 while (this.rootDom.firstChild) { this.rootDom.removeChild(this.rootDom.firstChild); } this.addons = {} as any; delete App.instances[this.appName]; }
内容的提问来源于stack exchange,提问作者JayceLin
相关产品推荐
相关产品推荐

