Rumah > Artikel > hujung hadapan web > Bagaimana untuk menambah nod pada pokok sebagai tindak balas
Cara menambah nod pada pokok dalam React: 1. Memperkenalkan kawalan pokok antd dan melaksanakan komponen berbentuk pokok melalui "const treeData = [...]" 2. Lulus nilai kunci nod semasa , dan kemudian melintasi tatasusunan data 3. Apabila melintasi tatasusunan untuk menambah nod, cuma tambahkan nod melalui algoritma pertanyaan objek tatasusunan bersarang.
Persekitaran pengendalian tutorial ini: Sistem Windows 10, bertindak balas versi 18.0.0, komputer Dell G3.
Bagaimana untuk menambah nod pada pokok sebagai tindak balas?
Projek React memperkenalkan kawalan pokok antd untuk melaksanakan penambahan, pemadaman dan pengubahsuaian nod
Apabila menyemak imbas beberapa soalan temu duga arus perdana, saya mendapati bahawa beberapa soalan temu bual meminta saya menulis penambahan, pemadaman dan pengubahsuaian fungsi kawalan pokok berdasarkan antd. pada asalnya saya fikir ia adalah komponen antd, tetapi saya tidak menjangkakan bahawa ia memerlukan banyak usaha apabila saya mula melakukannya. Jadi saya bercadang untuk merekodkan keseluruhan proses merealisasikan keperluan.
Rakan-rakan yang telah menggunakan antd harus tahu bahawa untuk menggunakan antd ialah menampal contoh kodnya, dan kemudian menggunakannya mengikut anda sendiri. keperluan dan API yang disediakan oleh antd. Jadi di sini saya juga mencari contoh kod kawalan pokok antd yang mudah, tidak kira apa, tampalkannya dahulu dan lihat apa hasilnya.
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> );}
Komponen ringkas berbentuk pokok dilaksanakan di sini, tetapi komponen ini pada asasnya tiada fungsi kecuali untuk menyemak imbas, jadi ia perlu diubah suai semula.
Secara amnya apabila menggunakan komponen antd, perkara yang paling penting ialah menggunakan API yang disediakan oleh antd. Walaupun kita tidak saya tahu bagaimana untuk menulisnya, tetapi ia sepatutnya agak mudah jika saya tahu cara menggunakannya. Apabila menyemak imbas API kawalan pokok, saya mendapati bahawa komponen <tree></tree>
mempunyai subkomponen <treenode></treenode>
, iaitu unit terkecil yang membentuk keseluruhan kawalan pokok. Jadi jika kita ingin melaksanakan penambahan, pemadaman dan pengubahsuaian, kita mesti bekerja keras pada komponen <treenode></treenode>
ini. Berdasarkan idea ini, ia kemudiannya diubah menjadi yang berikut.
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> );}
Kemudian ia kelihatan seperti ini:
Perkara yang perlu diperhatikan di sini ialah tajuk <treenode></treenode>
menerima data jenis ReactNode, jadi anda boleh mentakrifkannya sendiri berdasarkan ini Untuk memaparkan gaya data, seperti menambah ikon dan seumpamanya. Kemudian pada ketika ini, semua orang harus tahu. Bukankah keperluan mengatakan bahawa perlu ada fungsi penambahan, pemadaman dan pengubahsuaian Anda hanya boleh menggunakan tajuk ini untuk menunjukkannya di hadapan anda, dan kemudian anda boleh mengubahnya kod tersebut.
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> );}
Kini terdapat tiga butang Fungsi khusus masih tidak tersedia, jadi mari kita lakukannya satu persatu.
Tambah nod Kaedah pelaksanaan adalah untuk menghantar nilai kunci nod semasa dan kemudian merentasi tatasusunan data Apabila merentasi tatasusunan untuk menambah nod, ia melibatkan algoritma pertanyaan bagi objek tatasusunan bersarang, yang menggunakan idea-idea lintasan-pertama-dalam dan luas-dahulu bagi tatasusunan yang dipelajari dalam dua minggu sebelumnya.
Berikut ialah kod yang diubah suai berdasarkan idea ini:
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> );}
Klik butang Tambah untuk muncul nod lalai baharu:
Dengan idea menambah nod di atas, fungsi penyuntingan dan pemadaman seterusnya akan lebih mudah dilakukan. Hanya coretan kod ditunjukkan di sini dan versi akhir kod itu berada di penghujung artikel. Apabila mengedit nod, anda perlu menjadikan nod itu boleh diedit, jadi anda perlu menggunakan pembolehubah untuk mengurusnya.
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); } } });
5. Lengkapkan kod
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 = (Pembelajaran yang disyorkan: "video bertindak balas tutorial 》onChange(e, item.key)} />); } else { item.title = (onClose(item.key, item.defaultValue)} /> onSave(item.key)} /> {item.value}); } if (item.children) { return (onEdit(item.key)} /> onAdd(item.key)} /> {item.parentKey === "0" ? null : ( onDelete(item.key)} /> )} {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)}
Atas ialah kandungan terperinci Bagaimana untuk menambah nod pada pokok sebagai tindak balas. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!