中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

react如何給樹增加節點

發布時間:2023-01-28 10:32:36 來源:億速云 閱讀:174 作者:iii 欄目:web開發

這篇文章主要介紹“react如何給樹增加節點”,在日常操作中,相信很多人在react如何給樹增加節點問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”react如何給樹增加節點”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

react給樹增加節點的方法:1、引入antd的樹形控件,并通過“const treeData = [...]”實現tree形組件;2、把當前節點的key值傳遞過去,然后遍歷data數組;3、在遍歷數組增加節點時,通過嵌套數組對象的查詢算法實現增加節點即可。

React項目引入antd的樹形控件實現節點增刪改

一、 引入antd的樹形控件

使用過antd的小伙伴應該都知道,使用antd就是把它的代碼示例粘貼下來,然后根據自己的需求和antd提供的API進行更改。所以這里我也是找一個簡單antd樹形控件代碼示例,不管三七二十一先粘貼進去看看結果怎么樣。

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  treeData={treeData} />
   </div>
 );}

這里就實現了一個簡單的tree形組件,但是這個組件除了可以瀏覽之外,基本沒什么作用,所以還需要對它進行再度改造。
react如何給樹增加節點

二、 改造組件代碼結構

一般使用antd組件的時候,最重要的就是使用antd提供的API,咱們雖然不會寫,但是會用應該還是挺容易的。在瀏覽樹形控件的API時發現,<Tree/>組件有個子組件<TreeNode/>,它就是組成整個樹形控件的最小單元。所以我們如果要實現增刪改的話,就要在這個<TreeNode/>組件上下功夫。根據這個思路然后改造成如下的樣子。

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 title={item.title} key={item.key} dataRef={item}>
           {renderTreeNodes(item.children)}
         </TreeNode>
       );
     }

     return <TreeNode title={item.title} key={item.key} />;
   });

   return nodeArr;
 };

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

然后就是如下的樣子:
react如何給樹增加節點
這里要說明的一點是<TreeNode/>的title接收的是ReactNode類型數據,所以大家可以根據這個來自己定義要展示數據的樣式,比如加上icon之類的。然后到這里,大家應該就知道了,需求里面不是說要有增刪改的功能嗎,正好可以借助這個title來展示一下,勝利就在眼前,接著改造代碼。

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 style={{ marginLeft: 10 }} />

           <PlusOutlined style={{ marginLeft: 10 }} />
         
           <MinusOutlined style={{ marginLeft: 10 }} />
         </span>
       </div>
     );

     if (item.children) {
       return (
         <TreeNode title={item.title} key={item.key} dataRef={item}>
           {renderTreeNodes(item.children)}
         </TreeNode>
       );
     }

     return <TreeNode title={item.title} key={item.key} />;
   });

   return nodeArr;
 };

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

現在就有了三個按鈕了,具體功能還是沒有的,那就一個一個來唄。
react如何給樹增加節點

三、 實現增加節點功能

增加節點,實現方法就是把當前節點的key值傳遞過去然后遍歷data數組,在遍歷數組增加節點的時候,涉及到嵌套數組對象的查詢算法,這就用到了前兩周學習的數組的深度優先和廣度優先遍歷思想。
下面是根據這個思路修改的代碼:

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 style={{ marginLeft: 10 }} />

           <PlusOutlined style={{ marginLeft: 10 }} onClick={()=>onAdd(item.key)} />

           <MinusOutlined style={{ marginLeft: 10 }} />
         </span>
       </div>
     );

     if (item.children) {
       return (
         <TreeNode title={item.title} key={item.key} dataRef={item}>
           {renderTreeNodes(item.children)}
         </TreeNode>
       );
     }

     return <TreeNode title={item.title} key={item.key} />;
   });

   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>
 );}

點擊添加按鈕出現一個新的default節點:
react如何給樹增加節點

三、 實現編輯節點功能

有了上面增加的節點的思想以后,后面的編輯和刪除功能就比較好做了。這里只展示代碼片段,文章最后有最終版本的代碼。在編輯節點的時候要把該節點變成可編輯的狀態,所以有就需要用一個變量來管理它。

  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,
     },
   ],
 },];

四、 實現刪除節點功能

 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);
       }
     }
   });

五、完整代碼

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 = (
         <div>
           <input value={item.value ||''} onChange={(e) => onChange(e, item.key)} />

           <CloseOutlined
             style={{ marginLeft: 10 }}
             onClick={() => onClose(item.key, item.defaultValue)}
           />

           <CheckOutlined
             style={{ marginLeft: 10 }}
             onClick={() => onSave(item.key)}
           />
         </div>
       );
     } else {
       item.title = (
         <div>
           <span>{item.value}</span>
           <span>
             <EditOutlined
               style={{ marginLeft: 10 }}
               onClick={() => onEdit(item.key)}
             />

             <PlusOutlined
               style={{ marginLeft: 10 }}
               onClick={() => onAdd(item.key)}
             />
             {item.parentKey === "0" ? null : (
               <MinusOutlined
                 style={{ marginLeft: 10 }}
                 onClick={() => onDelete(item.key)}
               />
             )}
           </span>
         </div>
       );
     }

     if (item.children) {
       return (
         <TreeNode title={item.title} key={item.key} dataRef={item}>
           {renderTreeNodes(item.children)}
         </TreeNode>
       );
     }

     return <TreeNode title={item.title} key={item.key} />;
   });

   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 (
   <div>
     <Tree expandedKeys={expandedKeys} onExpand={onExpand}>
       {renderTreeNodes(data)}
     </Tree>
   </div>
 );}

到此,關于“react如何給樹增加節點”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

博兴县| 颍上县| 泽库县| 波密县| 塘沽区| 两当县| 新宁县| 博罗县| 安义县| 齐齐哈尔市| 玉门市| 中山市| 东乌珠穆沁旗| 呼和浩特市| 琼结县| 井冈山市| 乌什县| 十堰市| 黎平县| 东港市| 太和县| 资源县| 大理市| 关岭| 呼图壁县| 科技| 常山县| 天门市| 鄯善县| 盐山县| 定陶县| 兴城市| 抚宁县| 晋州市| 琼结县| 奉节县| 新余市| 宣化县| 湟源县| 安吉县| 军事|