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

React中AntD树形数据深层节点值修改方案咨询

解决AntD Tree深层节点修改问题(useState状态管理)

要修改树形数据中任意层级的节点,核心是通过递归遍历定位目标节点,同时遵循React不可变状态规则,创建新的树结构来更新状态,不能直接修改原数据。以下是具体实现方案:

1. 编写递归更新函数

这个函数负责遍历整个树形结构,找到匹配key的节点并返回新的节点对象,同时递归处理子节点:

// 递归更新树形节点,返回全新的树结构
const updateTreeItem = (treeData, targetKey, updateProps) => {
  return treeData.map(node => {
    // 匹配到目标节点,返回合并了更新属性的新节点
    if (node.key === targetKey) {
      return { ...node, ...updateProps };
    }
    // 存在子节点时,递归更新子节点数组
    if (node.children?.length) {
      return { ...node, children: updateTreeItem(node.children, targetKey, updateProps) };
    }
    // 无匹配且无子节点,返回原节点
    return node;
  });
};

2. 在组件中结合useState使用

将递归函数与useState结合,实现节点修改后的状态更新,同时对接AntD Tree组件:

import { useState } from 'react';
import { Tree, Modal, Input } from 'antd';

const MyTree = () => {
  const [treeData, setTreeData] = useState(dummyTreeData);
  const [visible, setVisible] = useState(false);
  const [currentKey, setCurrentKey] = useState('');
  const [newTitle, setNewTitle] = useState('');

  // 触发编辑弹窗
  const handleEdit = (key) => {
    setCurrentKey(key);
    // 递归获取原节点的title作为输入框初始值
    const getNodeTitle = (nodes) => {
      for (const node of nodes) {
        if (node.key === key) return node.title;
        if (node.children?.length) {
          const res = getNodeTitle(node.children);
          if (res) return res;
        }
      }
    };
    setNewTitle(getNodeTitle(treeData));
    setVisible(true);
  };

  // 确认修改节点
  const confirmUpdate = () => {
    if (!newTitle.trim()) return;
    const updatedTree = updateTreeItem(treeData, currentKey, { title: newTitle });
    setTreeData(updatedTree);
    setVisible(false);
  };

  return (
    <>
      <Tree
        treeData={treeData}
        defaultExpandAll
        onSelect={(keys) => handleEdit(keys[0])}
      />
      <Modal
        title="修改节点标题"
        visible={visible}
        onOk={confirmUpdate}
        onCancel={() => setVisible(false)}
      >
        <Input
          value={newTitle}
          onChange={(e) => setNewTitle(e.target.value)}
          placeholder="请输入新标题"
        />
      </Modal>
    </>
  );
};

// 你的示例树形数据
const dummyTreeData = [
  {
    title: 'parent 1',
    key: '1',
    children: [
      {
        title: 'parent 1-0',
        key: '1-0',
        disabled: true,
        children: [
          { title: 'leaf', key: '1-0-0', disableCheckbox: true },
          { title: 'leaf', key: '1-0-1' },
        ],
      },
      {
        title: 'parent 1-1',
        key: '1-1',
        children: [
          { title: <span style={{ color: '#1677ff' }}>sss</span>, key: '1-1-1' },
        ],
      },
    ],
  },
  {
    title: 'parent 2',
    key: '2',
    children: [
      {
        title: 'parent 2-0',
        key: '2-0',
        disabled: true,
        children: [
          { title: 'leaf', key: '2-0-0', disableCheckbox: true },
          { title: 'leaf', key: '2-0-1' },
        ],
      },
      {
        title: 'parent 2-1',
        key: '2-1',
        children: [
          { title: <span style={{ color: '#1677ff' }}>sss</span>, key: '2-1-1' },
        ],
      },
    ],
  },
];

export default MyTree;

关键说明

  • 支持修改任意层级节点:不管是顶层父节点、子节点还是孙节点,只要传入正确的key就能定位修改。
  • 遵循不可变状态:所有更新操作都通过创建新对象/数组完成,不会修改原数据,避免React状态更新异常。
  • 灵活扩展:如果需要修改disabled、children等其他属性,只需在updateProps中传入对应键值对即可,例如{ disabled: false, children: [] }。

内容的提问来源于stack exchange,提问作者Lee SeongBae

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 08:45:09