当前位置:首页 > React

react实现tree check

2026-01-27 08:48:02React

React 实现 Tree Check 功能

在 React 中实现树形结构的复选框(Tree Check)功能通常涉及递归渲染节点、管理选中状态以及处理父子节点的联动逻辑。以下是具体实现方法:

数据结构设计

树形结构的数据通常以嵌套对象形式表示,每个节点包含 idlabelchildren 等属性。例如:

const treeData = [
  {
    id: '1',
    label: 'Parent 1',
    children: [
      { id: '1-1', label: 'Child 1-1' },
      { id: '1-2', label: 'Child 1-2' },
    ],
  },
];

状态管理

使用 React 的 useStateuseReducer 管理选中状态。可以存储选中节点的 id 或完整路径:

const [checkedKeys, setCheckedKeys] = useState(new Set());

递归渲染树节点

通过递归组件渲染树形结构,并为每个节点添加复选框:

const TreeNode = ({ node, checkedKeys, onCheck }) => {
  const isChecked = checkedKeys.has(node.id);

  return (
    <div>
      <label>
        <input
          type="checkbox"
          checked={isChecked}
          onChange={() => onCheck(node.id, !isChecked)}
        />
        {node.label}
      </label>
      {node.children && (
        <div style={{ marginLeft: '20px' }}>
          {node.children.map(child => (
            <TreeNode
              key={child.id}
              node={child}
              checkedKeys={checkedKeys}
              onCheck={onCheck}
            />
          ))}
        </div>
      )}
    </div>
  );
};

处理选中逻辑

实现父子节点联动的核心逻辑:

  1. 选中父节点时自动选中所有子节点
  2. 取消父节点时自动取消所有子节点
  3. 部分选中子节点时父节点显示为半选状态
const updateCheckedKeys = (id, isChecked) => {
  const newCheckedKeys = new Set(checkedKeys);

  // 递归处理子节点
  const toggleChildren = (node) => {
    if (node.id === id) isChecked ? newCheckedKeys.add(id) : newCheckedKeys.delete(id);
    if (node.children) node.children.forEach(toggleChildren);
  };

  // 查找目标节点并更新
  const traverseTree = (nodes) => {
    nodes.forEach(node => {
      if (node.id === id || newCheckedKeys.has(id)) {
        toggleChildren(node);
      }
      if (node.children) traverseTree(node.children);
    });
  };

  traverseTree(treeData);
  setCheckedKeys(newCheckedKeys);
};

半选状态实现

通过计算子节点的选中状态决定父节点是否显示半选:

const isIndeterminate = (node) => {
  if (!node.children) return false;
  const childChecked = node.children.some(child => checkedKeys.has(child.id));
  const allChecked = node.children.every(child => checkedKeys.has(child.id));
  return childChecked && !allChecked;
};

在复选框属性中添加 indeterminate

<input
  type="checkbox"
  checked={isChecked}
  indeterminate={isIndeterminate(node)}
  onChange={() => onCheck(node.id, !isChecked)}
/>

完整示例代码

import React, { useState } from 'react';

const TreeCheck = ({ data }) => {
  const [checkedKeys, setCheckedKeys] = useState(new Set());

  const updateCheckedKeys = (id, isChecked) => {
    const newCheckedKeys = new Set(checkedKeys);
    const toggleChildren = (node) => {
      if (node.id === id) isChecked ? newCheckedKeys.add(id) : newCheckedKeys.delete(id);
      if (node.children) node.children.forEach(toggleChildren);
    };
    const traverseTree = (nodes) => {
      nodes.forEach(node => {
        if (node.id === id || newCheckedKeys.has(id)) toggleChildren(node);
        if (node.children) traverseTree(node.children);
      });
    };
    traverseTree(data);
    setCheckedKeys(newCheckedKeys);
  };

  const isIndeterminate = (node) => {
    if (!node.children) return false;
    const childChecked = node.children.some(child => checkedKeys.has(child.id));
    const allChecked = node.children.every(child => checkedKeys.has(child.id));
    return childChecked && !allChecked;
  };

  const TreeNode = ({ node }) => {
    const isChecked = checkedKeys.has(node.id);
    return (
      <div>
        <label>
          <input
            type="checkbox"
            checked={isChecked}
            indeterminate={isIndeterminate(node)}
            onChange={() => updateCheckedKeys(node.id, !isChecked)}
          />
          {node.label}
        </label>
        {node.children && (
          <div style={{ marginLeft: '20px' }}>
            {node.children.map(child => (
              <TreeNode key={child.id} node={child} />
            ))}
          </div>
        )}
      </div>
    );
  };

  return <div>{data.map(node => <TreeNode key={node.id} node={node} />)}</div>;
};

第三方库推荐

若需快速实现复杂功能,可考虑以下库:

  • react-checkbox-tree:专为树形复选框设计的组件。
  • rc-tree:Ant Design 的底层树组件,支持复选框。
  • downshift:灵活的可定制组件,适用于树形选择。

以上方法可根据实际需求调整,例如优化性能(如避免递归渲染)或添加异步加载子节点功能。

react实现tree check

标签: reacttree
分享给朋友:

相关文章

react native如何启动

react native如何启动

如何启动 React Native 项目 安装 Node.js 和 npm 确保已安装 Node.js(建议版本 16 或更高)和 npm(Node.js 自带)。可通过以下命令检查版本: node…

react 如何执行

react 如何执行

安装 Node.js 和 npm React 开发需要 Node.js 环境,因为它提供了 npm(或 yarn)包管理工具。从 Node.js 官网 下载并安装最新 LTS 版本。安装完成后,在终端…

电脑如何安装react

电脑如何安装react

安装 Node.js 和 npm React 依赖于 Node.js 和 npm(Node Package Manager)。从 Node.js 官网下载并安装最新稳定版本,安装完成后会自动包含 np…

vue实现tree

vue实现tree

Vue 实现 Tree 组件 在 Vue 中实现 Tree 组件可以通过递归组件或第三方库来完成。以下是两种常见方法: 递归组件实现 递归组件适合处理嵌套的树形数据。定义一个组件,该组件能够调用自身…

如何选购react

如何选购react

选购 React 相关产品或服务的建议 React 是一个用于构建用户界面的 JavaScript 库,广泛应用于前端开发。以下是选购 React 相关产品(如课程、书籍、工具、组件库等)的参考方法:…

react如何运行

react如何运行

运行React项目的步骤 安装Node.js 确保系统已安装Node.js(建议版本12以上),可从官网下载并安装。Node.js自带npm包管理器,用于后续依赖安装。 创建React项目 使用官方…