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

react-checkbox-tree含子节点的父节点无法勾选问题求助

修复react-checkbox-tree父节点无法勾选的问题

问题分析

你的代码中处理勾选状态的逻辑存在两个核心问题:

  • 父节点勾选时,childValues 始终为空数组,没有正确收集父节点自身及子节点的 value
  • 更新选中状态时直接替换数组,而非基于现有选中项进行增删,同时未处理父节点与子节点的勾选联动

修复后的代码

const nodes = [
  {
    value: "mars",
    label: "Mars",
    children: [
      {
        value: "phobos",
        label: "Phobos"
      },
      { value: "deimos", label: "Deimos" }
    ]
  },
  {
    value: "saturn",
    label: "Saturn" // 修正拼写错误
  },
  {
    value: "jupitor",
    label: "Jupiter" // 修正拼写错误
  }
];

function Widget() {
  const [checked, setChecked] = useState([]);
  const [expanded, setExpanded] = useState([]);

  // 递归收集节点及其所有子节点的value
  const collectAllNodeValues = (node) => {
    let values = [node.value];
    if (node.children && node.children.length > 0) {
      node.children.forEach(child => {
        values = [...values, ...collectAllNodeValues(child)];
      });
    }
    return values;
  };

  const updateCheckedState = (currentNode) => {
    const allNodeValues = collectAllNodeValues(currentNode);
    
    if (currentNode.checked) {
      // 勾选时,合并现有选中项与当前节点及子节点的value,去重
      setChecked([...new Set([...checked, ...allNodeValues])]);
    } else {
      // 取消勾选时,移除当前节点及子节点的所有value
      setChecked(checked.filter(item => !allNodeValues.includes(item)));
    }
  };

  return (
    <CheckboxTree
      iconsClass="fa5"
      nodes={nodes}
      checked={checked}
      expanded={expanded}
      onCheck={(nodes, node) => {
        updateCheckedState(node);
      }}
      onExpand={(expanded) => setExpanded(expanded)}
    />
  );
}

关键修改说明

  1. 新增递归收集函数:collectAllNodeValues 用于递归获取当前节点及其所有子节点的 value,确保父节点勾选时能包含自身和所有子节点
  2. 修正状态更新逻辑:
    • 勾选操作:合并现有选中数组与当前节点的所有关联value,用Set去重避免重复
    • 取消操作:过滤掉当前节点及其子节点的所有value
  3. 修正拼写错误:修复了节点label中的拼写错误,不影响功能但提升代码规范性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:26:55