React 树形组件 Tree View

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
注册配置 MSE Nacos/ZooKeeper,118元/月
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文从零开始构建了一个简单的React树形组件,介绍了环境准备、项目创建、基础组件构建等步骤,并探讨了常见问题及解决方案,包括层次嵌套过深、状态管理复杂、事件处理不当和样式问题,帮助读者在实际项目中更好地应用树形组件。

引言

树形组件(Tree View)是一种常见的UI组件,用于展示具有层次结构的数据。在React中,实现一个树形组件不仅能够提升用户体验,还能使数据展示更加清晰。本文将从零开始构建一个简单的React树形组件,探讨其中的常见问题、易错点及如何避免,并提供代码示例。
image.png

环境准备

在开始之前,确保你的开发环境中安装了以下工具:

  • Node.js 和 npm
  • Create React App

创建项目

首先,使用Create React App创建一个新的React项目:

npx create-react-app react-tree-view
cd react-tree-view

构建基础树形组件

定义数据结构

假设我们有一个简单的树形数据结构,每个节点包含idnamechildren属性。

const treeData = [
  {
   
    id: 1,
    name: 'Node 1',
    children: [
      {
   
        id: 2,
        name: 'Node 1.1',
        children: [
          {
   
            id: 3,
            name: 'Node 1.1.1'
          }
        ]
      },
      {
   
        id: 4,
        name: 'Node 1.2'
      }
    ]
  },
  {
   
    id: 5,
    name: 'Node 2',
    children: [
      {
   
        id: 6,
        name: 'Node 2.1'
      }
    ]
  }
];

创建树形组件

src目录下创建一个文件夹components,并在其中创建TreeView.js

import React from 'react';

const TreeNode = ({
    node, onToggle }) => {
   
  const hasChildren = node.children && node.children.length > 0;
  const [isExpanded, setIsExpanded] = React.useState(false);

  const handleToggle = () => {
   
    setIsExpanded(!isExpanded);
    onToggle(node.id, !isExpanded);
  };

  return (
    <div style={
   {
    paddingLeft: 20 }}>
      <div onClick={
   handleToggle} style={
   {
    cursor: 'pointer' }}>
        {
   hasChildren ? (isExpanded ? '-' : '+') : ''} {
   node.name}
      </div>
      {
   isExpanded && (
        <ul>
          {
   node.children.map((child) => (
            <TreeNode key={
   child.id} node={
   child} onToggle={
   onToggle} />
          ))}
        </ul>
      )}
    </div>
  );
};

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

export default TreeView;

使用树形组件

App.js中使用TreeView组件:

import React from 'react';
import TreeView from './components/TreeView';

const treeData = [
  {
   
    id: 1,
    name: 'Node 1',
    children: [
      {
   
        id: 2,
        name: 'Node 1.1',
        children: [
          {
   
            id: 3,
            name: 'Node 1.1.1'
          }
        ]
      },
      {
   
        id: 4,
        name: 'Node 1.2'
      }
    ]
  },
  {
   
    id: 5,
    name: 'Node 2',
    children: [
      {
   
        id: 6,
        name: 'Node 2.1'
      }
    ]
  }
];

function App() {
   
  return (
    <div className="App">
      <h1>Tree View</h1>
      <TreeView data={
   treeData} />
    </div>
  );
}

export default App;

常见问题及易错点

1. 层次嵌套过深

问题描述:当树形结构非常深时,递归渲染可能会导致性能问题。

解决方法:使用虚拟化技术(如react-window)来优化渲染性能。

2. 状态管理复杂

问题描述:随着树形结构的复杂度增加,状态管理变得越来越复杂。

解决方法:使用Redux或React Context来集中管理状态,避免组件之间的状态传递。

3. 事件处理不当

问题描述:在处理节点展开和折叠事件时,如果没有正确管理状态,可能会导致意外的行为。

解决方法:确保每个节点的状态独立管理,并在父组件中统一处理事件。

const TreeNode = ({
    node, onToggle, isExpanded }) => {
   
  const hasChildren = node.children && node.children.length > 0;

  const handleToggle = () => {
   
    onToggle(node.id);
  };

  return (
    <div style={
   {
    paddingLeft: 20 }}>
      <div onClick={
   handleToggle} style={
   {
    cursor: 'pointer' }}>
        {
   hasChildren ? (isExpanded ? '-' : '+') : ''} {
   node.name}
      </div>
      {
   isExpanded && (
        <ul>
          {
   node.children.map((child) => (
            <TreeNode key={
   child.id} node={
   child} onToggle={
   onToggle} isExpanded={
   isExpanded} />
          ))}
        </ul>
      )}
    </div>
  );
};

const TreeView = ({
    data }) => {
   
  const [expandedNodes, setExpandedNodes] = React.useState([]);

  const handleToggle = (id) => {
   
    setExpandedNodes((prev) => {
   
      if (prev.includes(id)) {
   
        return prev.filter((nodeId) => nodeId !== id);
      } else {
   
        return [...prev, id];
      }
    });
  };

  const isNodeExpanded = (id) => expandedNodes.includes(id);

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

4. 样式问题

问题描述:默认样式可能不符合需求,需要自定义样式。

解决方法:使用CSS或CSS-in-JS库(如styled-components)来定制样式。

import styled from 'styled-components';

const TreeNodeContainer = styled.div`
  padding-left: 20px;
  cursor: pointer;
`;

const TreeNode = ({
    node, onToggle, isExpanded }) => {
   
  const hasChildren = node.children && node.children.length > 0;

  const handleToggle = () => {
   
    onToggle(node.id);
  };

  return (
    <TreeNodeContainer onClick={
   handleToggle}>
      {
   hasChildren ? (isExpanded ? '-' : '+') : ''} {
   node.name}
      {
   isExpanded && (
        <ul>
          {
   node.children.map((child) => (
            <TreeNode key={
   child.id} node={
   child} onToggle={
   onToggle} isExpanded={
   isExpanded} />
          ))}
        </ul>
      )}
    </TreeNodeContainer>
  );
};

结论

通过本文的介绍,我们从零开始构建了一个简单的React树形组件,并探讨了常见的问题、易错点及如何避免。希望这些内容对你有所帮助,让你在实际项目中更好地应用树形组件。如果你有任何疑问或建议,欢迎留言交流。

目录
相关文章
|
15天前
|
存储 人工智能 弹性计算
阿里云弹性计算_加速计算专场精华概览 | 2024云栖大会回顾
2024年9月19-21日,2024云栖大会在杭州云栖小镇举行,阿里云智能集团资深技术专家、异构计算产品技术负责人王超等多位产品、技术专家,共同带来了题为《AI Infra的前沿技术与应用实践》的专场session。本次专场重点介绍了阿里云AI Infra 产品架构与技术能力,及用户如何使用阿里云灵骏产品进行AI大模型开发、训练和应用。围绕当下大模型训练和推理的技术难点,专家们分享了如何在阿里云上实现稳定、高效、经济的大模型训练,并通过多个客户案例展示了云上大模型训练的显著优势。
|
18天前
|
存储 人工智能 调度
阿里云吴结生:高性能计算持续创新,响应数据+AI时代的多元化负载需求
在数字化转型的大潮中,每家公司都在积极探索如何利用数据驱动业务增长,而AI技术的快速发展更是加速了这一进程。
|
9天前
|
并行计算 前端开发 物联网
全网首发!真·从0到1!万字长文带你入门Qwen2.5-Coder——介绍、体验、本地部署及简单微调
2024年11月12日,阿里云通义大模型团队正式开源通义千问代码模型全系列,包括6款Qwen2.5-Coder模型,每个规模包含Base和Instruct两个版本。其中32B尺寸的旗舰代码模型在多项基准评测中取得开源最佳成绩,成为全球最强开源代码模型,多项关键能力超越GPT-4o。Qwen2.5-Coder具备强大、多样和实用等优点,通过持续训练,结合源代码、文本代码混合数据及合成数据,显著提升了代码生成、推理和修复等核心任务的性能。此外,该模型还支持多种编程语言,并在人类偏好对齐方面表现出色。本文为周周的奇妙编程原创,阿里云社区首发,未经同意不得转载。
|
22天前
|
缓存 监控 Linux
Python 实时获取Linux服务器信息
Python 实时获取Linux服务器信息
|
8天前
|
人工智能 自然语言处理 前端开发
什么?!通义千问也可以在线开发应用了?!
阿里巴巴推出的通义千问,是一个超大规模语言模型,旨在高效处理信息和生成创意内容。它不仅能在创意文案、办公助理、学习助手等领域提供丰富交互体验,还支持定制化解决方案。近日,通义千问推出代码模式,基于Qwen2.5-Coder模型,用户即使不懂编程也能用自然语言生成应用,如个人简历、2048小游戏等。该模式通过预置模板和灵活的自定义选项,极大简化了应用开发过程,助力用户快速实现创意。
|
5天前
|
云安全 存储 弹性计算
|
7天前
|
云安全 人工智能 自然语言处理
|
4天前
|
人工智能 C++ iOS开发
ollama + qwen2.5-coder + VS Code + Continue 实现本地AI 辅助写代码
本文介绍在Apple M4 MacOS环境下搭建Ollama和qwen2.5-coder模型的过程。首先通过官网或Brew安装Ollama,然后下载qwen2.5-coder模型,可通过终端命令`ollama run qwen2.5-coder`启动模型进行测试。最后,在VS Code中安装Continue插件,并配置qwen2.5-coder模型用于代码开发辅助。
330 4
|
4天前
|
缓存 Linux Docker
【最新版正确姿势】Docker安装教程(简单几步即可完成)
之前的老版本Docker安装教程已经发生了变化,本文分享了Docker最新版安装教程,其他操作系统版本也可以参考官 方的其他安装版本文档。
【最新版正确姿势】Docker安装教程(简单几步即可完成)
|
10天前
|
人工智能 自然语言处理 前端开发
用通义灵码,从 0 开始打造一个完整APP,无需编程经验就可以完成
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。本教程完全免费,而且为大家准备了 100 个降噪蓝牙耳机,送给前 100 个完成的粉丝。获奖的方式非常简单,只要你跟着教程完成第一课的内容就能获得。