ant design react 树形结构详解_ant design

import React, { useEffect, useState, useMemo } from 'react';
import { Input, Tree } from 'antd';
const { Search } = Input;

let treeList = [
  {
    title: 'Node 1',
    key: '0-0',
    children: [
      {
        title: 'Child Node 1-1',
        key: '0-0-0',
        children: [
          {
            title: 'Grandchild Node 1-1-1',
            key: '0-0-0-0',
          },
          {
            title: 'Grandchild Node 1-1-2',
            key: '0-0-0-1',
          },
        ],
      },
      {
        title: 'Child Node 1-2',
        key: '0-0-1',
      },
    ],
  },
  {
    title: 'Node 2',
    key: '0-1',
    children: [
      {
        title: 'Child Node 2-1',
        key: '0-1-0',
      },
    ],
  },
  {
    title: 'Node 3',
    key: '0-2',
  },
];

const TreeBox = () => {
  const [expandedKeys, setExpandedKeys] = useState([]);
  const [searchValue, setSearchValue] = useState('');
  const [autoExpandParent, setAutoExpandParent] = useState(true);
  const [treeData, setTreeData] = useState([]);

  useEffect(() => {
    // 初始化数据
    setTreeData(treeList);
  }, []);

  const onExpand = (newExpandedKeys) => {
    setExpandedKeys(newExpandedKeys);
    setAutoExpandParent(false);
  };

  const onChange = (e) => {
    const { value } = e.target;
    const newExpandedKeys = treeData
      .flatMap((item) => {
        if (item.title.includes(value)) {
          return [item.key];
        }
        return item.children
          ? item.children.flatMap((child) => {
              if (child.title.includes(value)) {
                return [child.key];
              }
              return [];
            })
          : [];
      })
      .filter((item, i, self) => !!(item && self.indexOf(item) === i));
    setExpandedKeys(newExpandedKeys);
    setSearchValue(value);
    setAutoExpandParent(true);
  };

  const treeDataFiltered = useMemo(() => {
    const loop = (data) =>
      data.map((item) => {
        const strTitle = item.title;
        const index = strTitle.indexOf(searchValue);
        const beforeStr = strTitle.substring(0, index);
        const afterStr = strTitle.slice(index + searchValue.length);
        const title =
          index > -1 ? (
            <span key={item.key}>
              {beforeStr}
              <span className="site-tree-search-value">{searchValue}</span>
              {afterStr}
            </span>
          ) : (
            <span key={item.key}>{strTitle}</span>
          );
        if (item.children) {
          return {
            title,
            key: item.key,
            children: loop(item.children),
          };
        }
        return {
          title,
          key: item.key,
        };
      });
    return loop(treeData);
  }, [searchValue, treeData]);

  return (
    <div>
      <Search
        style={{
          marginBottom: 8,
        }}
        placeholder="Search"
        onChange={onChange}
      />
      <Tree
        onExpand={onExpand}
        expandedKeys={expandedKeys}
        autoExpandParent={autoExpandParent}
        treeData={treeDataFiltered}
      />
    </div>
  );
};

export default TreeBox;

代码解析

导入模块

  • React: 主要用于声明式地创建组件。
  • useEffectuseStateuseMemo: React Hooks,分别用于处理副作用、状态管理和性能优化。
  • InputTree: Ant Design 的输入框和树形选择器组件。

初始数据

  • treeList: 一个模拟的数据列表,用于初始化树形结构。

定义组件

  • TreeBox: 一个基于 React 的函数组件。

状态管理

  • expandedKeys: 存储当前展开的节点键值数组。
  • searchValue: 当前搜索框的值。
  • autoExpandParent: 控制是否自动展开父节点。
  • treeData: 当前展示的树形数据。

副作用处理

  • useEffect: 在组件首次渲染时初始化数据。
  • setTreeData(treeList): 将初始数据设置给 treeData

事件处理

  • onExpand: 展开节点时触发。
  • newExpandedKeys: 新的展开键值数组。
  • 更新状态 expandedKeys 和 autoExpandParent
  • onChange: 搜索框内容改变时触发。
  • value: 新的搜索值。
  • 根据搜索值计算新的展开键值数组。
  • 更新状态 expandedKeyssearchValue, 和 autoExpandParent

数据处理

  • treeDataFiltered: 通过 useMemo 缓存的经过过滤的树形数据。
  • loop: 递归函数,用于遍历树形数据并进行高亮处理。
  • index: 查找搜索值的位置。
  • beforeStrafterStr: 分别是搜索值之前和之后的字符串。
  • title: 根据搜索值生成带有高亮的标题。

渲染

  • Search: 搜索框组件。
  • Tree: 树形选择器组件。
  • onExpand: 展开事件处理器。
  • expandedKeys: 展开的键值数组。
  • autoExpandParent: 是否自动展开父节点。
  • treeData: 渲染的树形数据。

详细解释

  1. treeList
  • 是一个模拟的树形数据列表,用于初始化树形结构。
  1. expandedKeys
  • 用于存储当前已展开的节点的键值。
  • 初始化为空数组。
  1. searchValue
  • 存储搜索框中的值。
  • 初始化为空字符串。
  1. autoExpandParent
  • 控制是否自动展开父节点。
  • 初始化为 true
  1. treeData
  • 存储当前展示的树形数据。
  • 初始化为 treeList
  1. useEffect
  • 用于在组件挂载时初始化数据。
  • 设置 treeData 为 treeList
  1. onExpand
  • 当用户点击展开或折叠节点时触发。
  • 更新 expandedKeys 和 autoExpandParent
  1. onChange
  • 当搜索框的内容发生变化时触发。
  • 根据新的搜索值计算需要展开的节点键值。
  • 更新 expandedKeyssearchValue 和 autoExpandParent
  1. useMemo
  • 用于优化性能,避免不必要的重新渲染。
  • 计算经过搜索过滤和高亮处理的树形数据。
  1. loop
  • 递归函数,用于遍历树形数据并根据搜索值进行高亮处理。
  • 如果找到匹配的节点,则生成带有高亮效果的标题。
  1. 返回的 JSX
  • 包含搜索框和树形选择器。
  • 树形选择器使用 treeDataFiltered 作为数据源。