search
HomeWeb Front-endFront-end Q&AHow to add nodes to tree in react
How to add nodes to tree in reactJan 18, 2023 pm 02:09 PM
reactnode

How to add nodes to the tree in react: 1. Introduce antd's tree control and implement tree-shaped components through "const treeData = [...]"; 2. Pass the key value of the current node , and then traverse the data array; 3. When traversing the array to add nodes, just add nodes through the query algorithm of nested array objects.

How to add nodes to tree in react

The operating environment of this tutorial: Windows 10 system, react18.0.0 version, Dell G3 computer.

How to add nodes to the tree in react?

The React project introduces antd's tree control to implement node addition, deletion and modification

Preface

When browsing some mainstream interview questions, I found that some interview questions asked me to write the addition, deletion and modification functions of a tree control based on antd. I originally thought that it was a component of antd. It should be pretty simple, but I didn’t expect that it took a lot of effort when I started doing it. So I plan to record the entire process of realizing the requirements.

1. Introducing antd's tree control

Everyone who has used antd should know that to use antd is to paste its code example, and then use it according to your own requirements and the API provided by antd. So here I am also looking for a simple antd tree control code example, no matter what, paste it in first and see what the result is.

import React from "react";
import { Tree } from "antd";const treeData = [
  {
    title: "0-0",
    key: "0-0",
    children: [
      {
        title: "0-0-0",
        key: "0-0-0",
        children: [
          { title: "0-0-0-0", key: "0-0-0-0" },
          { title: "0-0-0-1", key: "0-0-0-1" },
          { title: "0-0-0-2", key: "0-0-0-2" },
        ],
      },
      {
        title: "0-0-1",
        key: "0-0-1",
        children: [
          { title: "0-0-1-0", key: "0-0-1-0" },
          { title: "0-0-1-1", key: "0-0-1-1" },
          { title: "0-0-1-2", key: "0-0-1-2" },
        ],
      },
      {
        title: "0-0-2",
        key: "0-0-2",
      },
    ],
  },
  {
    title: "0-1",
    key: "0-1",
    children: [
      { title: "0-1-0-0", key: "0-1-0-0" },
      { title: "0-1-0-1", key: "0-1-0-1" },
      { title: "0-1-0-2", key: "0-1-0-2" },
    ],
  },
  {
    title: "0-2",
    key: "0-2",
  },];export default function TreeDemo() {
  return (
    <div>
      <tree></tree>
    </div>
  );}

A simple tree-shaped component is implemented here, but this component has basically no function except for browsing, so it needs to be reshaped.
How to add nodes to tree in react

2. Transform the component code structure

Generally when using antd components, the most important thing is to use the API provided by antd. Although we do not You know how to write it, but it should be pretty easy if you know how to use it. When browsing the API of the tree control, I found that the <tree></tree> component has a sub-component <treenode></treenode>, which is the smallest unit that makes up the entire tree control. So if we want to implement additions, deletions and modifications, we must work hard on this <treenode></treenode> component. Based on this idea, it is then transformed into the following.

import React, { useState } from "react";import { Tree } from "antd";const { TreeNode } = Tree;const treeData = [
  {
    value: "0",
    key: "0",
    children: [
      {
        value: "0-1",
        key: "0-1",
      },
      {
        value: "0-2",
        key: "0-2",
      },
    ],
  },];export default function TreeDemo() {
  const [data, setdata] = useState(treeData);
  const renderTreeNodes = (data) => {
    let nodeArr = data.map((item) => {
      item.title = <span>{item.value}</span>;

      if (item.children) {
        return (
          <treenode>
            {renderTreeNodes(item.children)}
          </treenode>
        );
      }

      return <treenode></treenode>;
    });

    return nodeArr;
  };

  return (
    <div>
      <tree>{renderTreeNodes(data)}</tree>
    </div>
  );}

Then it looks like the following:
How to add nodes to tree in react
The point to note here is that the title of <treenode></treenode> receives ReactNode type data, so You can use this to define your own style for displaying data, such as adding icons and the like. Then at this point, everyone should know that the requirements say that there should be addition, deletion and modification functions. You can use this title to show it. The victory is right in front of you, and then you can transform the code.

import React, { useState } from "react";import { Tree } from "antd";import {
    EditOutlined,
    PlusOutlined,
    MinusOutlined,
  } from "@ant-design/icons";const { TreeNode } = Tree;const treeData = [
  {
    value: "0",
    key: "0",
    children: [
      {
        value: "0-1",
        key: "0-1",
      },
      {
        value: "0-2",
        key: "0-2",
      },
    ],
  },];export default function TreeDemo() {
  const [data, setdata] = useState(treeData);
  const renderTreeNodes = (data) => {
    let nodeArr = data.map((item) => {
      item.title = (
        <div>
          <span>{item.value}</span>
          <span>
            <editoutlined></editoutlined>

            <plusoutlined></plusoutlined>
           
            <minusoutlined></minusoutlined>
          </span>
        </div>
      );

      if (item.children) {
        return (
          <treenode>
            {renderTreeNodes(item.children)}
          </treenode>
        );
      }

      return <treenode></treenode>;
    });

    return nodeArr;
  };

  return (
    <div>
      <tree>{renderTreeNodes(data)}</tree>
    </div>
  );}

Now there are three buttons, but the specific functions are still not available, so let’s do them one by one.
How to add nodes to tree in react

3. Implement the function of adding nodes

To add nodes, the method is to pass the key value of the current node and then traverse the data array. When traversing the array to add nodes, it involves the query algorithm of nested array objects, which uses the depth-first and breadth-first traversal ideas of arrays learned in the previous two weeks.
The following is the code modified based on this idea:

import React, { useState } from "react";import { Tree } from "antd";import { EditOutlined, PlusOutlined, MinusOutlined } from "@ant-design/icons";const { TreeNode } = Tree;const treeData = [
  {
    value: "0",
    key: "0",
    children: [
      {
        value: "0-1",
        key: "0-1",
      },
      {
        value: "0-2",
        key: "0-2",
      },
    ],
  },];export default function TreeDemo() {
  const [data, setdata] = useState(treeData);

  const renderTreeNodes = (data) => {
    let nodeArr = data.map((item) => {
      item.title = (
        <div>
          <span>{item.value}</span>
          <span>
            <editoutlined></editoutlined>

            <plusoutlined>onAdd(item.key)} />

            <minusoutlined></minusoutlined>
          </plusoutlined></span>
        </div>
      );

      if (item.children) {
        return (
          <treenode>
            {renderTreeNodes(item.children)}
          </treenode>
        );
      }

      return <treenode></treenode>;
    });

    return nodeArr;
  };

  const onAdd = (key) => {
    addNode(key,treeData); 
    //useState里数据务必为immutable (不可赋值的对象),所以必须加上slice()返回一个新的数组对象
    setdata(treeData.slice())
  };

  const addNode = (key,data) =>
    data.forEach((item) => {
      if (item.key === key) {
        if (item.children) {
          item.children.push({
            value: "default",
            key: key + Math.random(100), // 这个 key 应该是唯一的
          });
        } else {
          item.children = [];
          item.children.push({
            value: "default",
            key: key + Math.random(100),
          });
        }
        return;
      }
      if (item.children) {
       addNode(key, item.children);
      }
    });

  return (
    <div>
      <tree>{renderTreeNodes(data)}</tree>
    </div>
  );}

Click the Add button to appear a new default node:
How to add nodes to tree in react

3. Implementation Edit node function

With the idea of ​​adding nodes above, the subsequent editing and deletion functions will be easier to do. Only code snippets are shown here, and the final version of the code is at the end of the article. When editing a node, you need to make the node editable, so you need to use a variable to manage it.

  const onEdit = (key) => {
    editNode(key, treeData);
    setData(treeData.slice())
  };

  const editNode = (key, data) =>
    data.forEach((item) => {
      if (item.key === key) {
        item.isEditable = true;
      } else {
        item.isEditable = false;
      }
      item.value = item.defaultValue; // 当某节点处于编辑状态,并改变数据,点击编辑其他节点时,此节点变成不可编辑状态,value 需要回退到 defaultvalue
      if (item.children) {
        editNode(key, item.children);
      }
    });const treeData = [
  {
    value: "0",
    key: "0",
    isEditable: false,
    children: [
      {
        value: "0-1",
        key: "0-1",
        isEditable: false,
      },
      {
        value: "0-2",
        key: "0-2",
        isEditable: false,
      },
    ],
  },];

4. Implement the delete node function

 const onDelete = (key) => {
    deleteNode(key, treeData);
    setData(treeData.slice());
  };

  const deleteNode = (key, data) =>
    data.forEach((item, index) => {
      if (item.key === key) {
        data.splice(index, 1);
        return;
      } else {
        if (item.children) {
          deleteNode(key, item.children);
        }
      }
    });

5. Complete code

import React, { useState} from "react";import { Tree } from "antd";import {
  EditOutlined,
  PlusOutlined,
  MinusOutlined,
  CloseOutlined,
  CheckOutlined,} from "@ant-design/icons";import {nanoid} from "nanoid";const { TreeNode } = Tree;const treeData = [
  {
    value: "0",
    defaultValue: "0",
    key: "0",
    parentKey: '0',
    isEditable: false,
    children: [
      {
        value: "0-1",
        key: "0-1",
        defaultValue: "0-1",
        isEditable: false,
      },
      {
        value: "0-2",
        key: "0-2",
        defaultValue: "0-2",
        isEditable: false,
      },
    ],
  },];const expandedKeyArr = ["0"];export default function TreeDemo() {
  const [data, setData] = useState(treeData);
  const [expandedKeys, setExpandedKeys] = useState(expandedKeyArr);

  const onExpand = (expandedKeys) => {
    //记录折叠的key值
    setExpandedKeys(expandedKeys);
  };
  const renderTreeNodes = (data) => {
    let nodeArr = data.map((item) => {
      if (item.isEditable) {
        item.title = (
          
             onChange(e, item.key)} />              onClose(item.key, item.defaultValue)}             />              onSave(item.key)}             />           
        );       } else {         item.title = (           
            {item.value}                             onEdit(item.key)}               />                onAdd(item.key)}               />               {item.parentKey === "0" ? null : (                  onDelete(item.key)}                 />               )}                        
        );       }       if (item.children) {         return (                        {renderTreeNodes(item.children)}                    );       }       return <treenode></treenode>;     });     return nodeArr;   };   const onAdd = (key) => {     if (expandedKeys.indexOf(key) === -1) {       expandedKeyArr.push(key);     }     setExpandedKeys(expandedKeyArr.slice());     addNode(key, treeData);     //useState里数据务必为immutable (不可赋值的对象),所以必须加上slice()返回一个新的数组对象     setData(treeData.slice());   };   const onEdit = (key) => {     editNode(key, treeData);     setData(treeData.slice());   };   const editNode = (key, data) =>     data.forEach((item) => {       if (item.key === key) {         item.isEditable = true;       } else {         item.isEditable = false;       }       item.value = item.defaultValue; // 当某节点处于编辑状态,并改变数据,点击编辑其他节点时,此节点变成不可编辑状态,value 需要回退到 defaultvalue       if (item.children) {         editNode(key, item.children);       }     });   const addNode = (key, data) =>     data.forEach((item) => {       if (item.key === key) {         if (item.children) {           item.children.push({             value: "default",             key: nanoid(), // 这个 key 应该是唯一的           });         } else {           item.children = [];           item.children.push({             value: "default",             key: nanoid(),           });         }         return;       }       if (item.children) {         addNode(key, item.children);       }     });   const onChange = (e, key) => {     changeNode(key, e.target.value, treeData);     setData(treeData.slice());   };   const changeNode = (key, value, data) =>     data.forEach((item) => {       if (item.key === key) {         item.value = value;       }       if (item.children) {         changeNode(key, value, item.children);       }     });   const onSave = (key) => {     saveNode(key, treeData);     setData(treeData.slice());   };   const saveNode = (key, data) =>     data.forEach((item) => {       if (item.key === key) {         item.defaultValue = item.value;       }       if (item.children) {         saveNode(key, item.children);       }       item.isEditable = false;     });   const onClose = (key, defaultValue) => {     closeNode(key, defaultValue, treeData);     setData(treeData);   };   const closeNode = (key, defaultValue, data) =>     data.forEach((item) => {       item.isEditable = false;       if (item.key === key) {         item.value = defaultValue;       }       if (item.children) {         closeNode(key, defaultValue, item.children);       }     });   const onDelete = (key) => {     deleteNode(key, treeData);     setData(treeData.slice());   };   const deleteNode = (key, data) =>     data.forEach((item, index) => {       if (item.key === key) {         data.splice(index, 1);         return;       } else {         if (item.children) {           deleteNode(key, item.children);         }       }     });   return (     
               {renderTreeNodes(data)}            
  );}
recommends learning: "react video tutorial"

The above is the detailed content of How to add nodes to tree in react. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
react中antd和dva是什么意思react中antd和dva是什么意思Apr 21, 2022 pm 03:25 PM

在react中,antd是基于Ant Design的React UI组件库,主要用于研发企业级中后台产品;dva是一个基于redux和“redux-saga”的数据流方案,内置了“react-router”和fetch,可理解为应用框架。

React是双向数据流吗React是双向数据流吗Apr 21, 2022 am 11:18 AM

React不是双向数据流,而是单向数据流。单向数据流是指数据在某个节点被改动后,只会影响一个方向上的其他节点;React中的表现就是数据主要通过props从父节点传递到子节点,若父级的某个props改变了,React会重渲染所有子节点。

react中为什么使用nodereact中为什么使用nodeApr 21, 2022 am 10:34 AM

因为在react中需要利用到webpack,而webpack依赖nodejs;webpack是一个模块打包机,在执行打包压缩的时候是依赖nodejs的,没有nodejs就不能使用webpack,所以react需要使用nodejs。

react是组件化开发吗react是组件化开发吗Apr 22, 2022 am 10:44 AM

react是组件化开发;组件化是React的核心思想,可以开发出一个个独立可复用的小组件来构造应用,任何的应用都会被抽象成一颗组件树,组件化开发也就是将一个页面拆分成一个个小的功能模块,每个功能完成自己这部分独立功能。

react中forceupdate的用法是什么react中forceupdate的用法是什么Apr 19, 2022 pm 12:03 PM

在react中,forceupdate()用于强制使组件跳过shouldComponentUpdate(),直接调用render(),可以触发组件的正常生命周期方法,语法为“component.forceUpdate(callback)”。

react有没有双向绑定react有没有双向绑定Apr 21, 2022 am 10:24 AM

react中没有双向绑定;react的设计思想就是单向数据流,没有双向绑定的概念;react是view层,单项数据流只能由父组件通过props将数据传递给子组件,满足了view层渲染的要求并且更易测试与控制,所以在react中没有双向绑定。

react native怎么删除组件react native怎么删除组件Apr 21, 2022 pm 04:10 PM

react native可以利用“npm uninstall --save 组件”删除组件;npm可用于管理第三方组件包,参数设置为uninstall时,可用于删除软件包,参数“--save”表示会从“packages.json”中获取包。

VSCode插件分享:一个实时预览Vue/React组件的插件VSCode插件分享:一个实时预览Vue/React组件的插件Mar 17, 2022 pm 08:07 PM

在VSCode中开发Vue/React组件时,怎么实时预览组件?本篇文章就给大家分享一个VSCode 中实时预览Vue/React组件的插件,希望对大家有所帮助!

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools