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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:45:03