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

React嵌套JSON渲染为带input的嵌套ul li结构的问题及最佳实践

现有代码问题
  • 遍历逻辑错误:调用map时没有收集遍历返回的节点数组,每次遍历直接覆盖children、sub_children变量值,最终只会保留最后一次遍历的单个子节点,其余子节点全部丢失。
  • 层级硬编码:仅手动处理了两层子节点的渲染逻辑,若JSON嵌套层级超过3层就会丢失深层节点,完全没有可扩展性。
  • 键值使用错误:列表项的key属性使用了遍历下标index,若后续列表发生增删、排序操作会触发渲染异常,应该使用节点唯一业务标识id作为key。
  • 代码耦合度高:所有逻辑堆叠在render方法中,难以维护和扩展。
最佳实现方案

这类无限层级的树结构渲染场景,最优解是使用递归渲染逻辑,将单个树节点的渲染逻辑抽离为公共方法,自动识别嵌套层级完成渲染,无需手动处理每一层级:

// 抽离公共递归渲染方法,支持任意层级嵌套
const renderTreeNode = (node) => {
  return (
    <li key={node.id}>
      <input defaultValue={node.name} />
      {/* 存在子节点时递归调用自身渲染子列表 */}
      {node.children?.length > 0 && (
        <ul>
          {node.children.map(child => renderTreeNode(child))}
        </ul>
      )}
    </li>
  )
}

class Hello extends React.Component {
  // 静态数据移到组件实例属性,避免每次render重复声明
  treeData = {"success":true,"message":"Show All Categories In Tree","data":[{"id":1,"name":"a","slug":"a","order":1,"children":[{"id":2,"name":"comic book","slug":"comic book","order":2,"children":[{"id":3,"name":"Manway Comic Book","slug":"Manway Comic Book","order":3},{"id":4,"name":"Luxury comic book","slug":"Luxury comic book","order":4},{"id":5,"name":"Action comic book","slug":"Action comic book","order":5}]},{"id":6,"name":"textbook","slug":"textbook","order":1,"children":[{"id":7,"name":"commercial","slug":"commercial","order":2},{"id":8,"name":"finance","slug":"finance","order":3},{"id":9,"name":"Computer Science","slug":"Computer Science","order":4}]}]},{"id":10,"name":"electrical","slug":"electrical","order":1,"children":[{"id":11,"name":"TV","slug":"TV","order":2,"children":[{"id":12,"name":"monitor","slug":"monitor","order":3},{"id":13,"name":"Blu-ray","slug":"Blu-ray","order":3}]},{"id":14,"name":"phone","slug":"phone","order":1,"children":[{"id":15,"name":"Huawei","slug":"Huawei","order":3},{"id":16,"name":"iPhone","slug":"iPhone","order":3},{"id":17,"name":"samsung","slug":"samsung","order":3}]}]},{"id":20,"name":"xx","order":1}]};

  render() {
    return <div>
      <ul>
        {this.treeData.data.map(node => renderTreeNode(node))}
      </ul>
    </div>;
  }
}

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

配套HTML结构保持不变即可:

<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="container">
</div>

该方案优势:

  • 自动适配任意嵌套层级,无需硬编码层级逻辑
  • 节点渲染逻辑统一维护,后续需要新增节点编辑、勾选等功能时可直接在renderTreeNode中修改
  • 使用节点唯一id作为key,避免列表渲染异常
  • 代码结构清晰,耦合度低

内容的提问来源于stack exchange,提问作者Jack The Baker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 17:27:01