react.js项目调用appendChild生成侧边栏出现重复aside实例问题求助
问题原因
- 首先是React 18+开发环境默认开启的严格模式导致:严格模式下组件会被执行两次挂载逻辑,你的
renderSideBar方法每次调用都会直接往body插入新的aside元素,两次调用就生成了两个重复节点,生产环境关闭严格模式后这个问题会消失,但这不是根本解决方法。 - 其次你完全脱离了React的渲染逻辑:React基于虚拟DOM管理页面节点,你直接用原生DOM API往全局
body插入元素,这些节点不受React状态管理,组件重渲染时也不会自动清理旧节点,后续如果组件更新还会出现更多重复节点。 - 额外问题:你的
renderSideBar里的li、a元素只在循环外创建了一次,循环中只是修改属性,最终生成的列表只会展示最后一条li_data的内容,无法正常渲染所有菜单。
修复方案
快速临时修复
如果暂时不想改动现有逻辑,在创建aside前先判断是否已经存在同ID节点,存在就不再重复创建:
// 在renderSideBar方法最开始加这段 if(document.querySelector('aside#sidebar')) return false;
同时把li和a的创建逻辑移到循环内部:
for (let i = 0; i < li_data.length;i++) { const li = document.createElement("li"); const a = document.createElement("a"); a.innerHTML = li_data[i][0]; a.href = li_data[i][1]; ul.appendChild(li); li.appendChild(a); }
正确的React实现方案
不要用原生DOM操作,直接把侧边栏封装为React组件,用JSX渲染:
// SideBar.jsx const SideBar = ({background, textColor, menuData}) => { return <aside id="sidebar" style={{background, color: textColor}}> <ul className="sidebar__ul" style={{listStyle: 'none'}}> {menuData.map(([menuName, menuPath], idx) => ( <li key={idx}> <a href={menuPath}>{menuName}</a> </li> ))} </ul> </aside> } export default SideBar
然后在App.js中直接引入使用:
import './App.css'; import SideBar from './SideBar'; function App() { return <SideBar background="#0275d8" textColor="white" menuData={[ ['Home', '/'], ['home', '/'] ]} /> } export default App
这种写法完全遵循React的渲染逻辑,不会出现重复生成节点的问题,后续维护也更简单。
内容的提问来源于stack exchange,提问作者Omar Khaled
相关产品推荐
相关产品推荐

