Maison  >  Article  >  interface Web  >  Comment ajouter des nœuds à l'arborescence en réaction

Comment ajouter des nœuds à l'arborescence en réaction

藏色散人
藏色散人original
2023-01-18 14:09:141496parcourir

Comment ajouter des nœuds à l'arborescence dans React : 1. Présentez le contrôle d'arborescence d'antd et implémentez les composants en forme d'arborescence via "const treeData = [...]" ; 2. Passez la valeur clé du nœud actuel, puis parcourez le data Tableau;3. Lorsque vous parcourez le tableau pour ajouter des nœuds, ajoutez simplement des nœuds via l'algorithme de requête des objets du tableau imbriqués.

Comment ajouter des nœuds à l'arborescence en réaction

L'environnement d'exploitation de ce tutoriel : système Windows 10, React version 18.0.0, ordinateur Dell G3.

Comment ajouter des nœuds à l'arborescence en réaction ?

Le projet React introduit le contrôle d'arborescence d'antd pour implémenter l'ajout, la suppression et la modification de nœuds

Avant-propos

En parcourant certaines questions d'entretien grand public, j'ai constaté que certaines questions d'entretien vous obligent à écrire une réponse basée sur antd Au départ, je pensais que le composant antd devrait être assez simple à ajouter, supprimer et modifier le contrôle d'arborescence, mais je ne m'attendais pas à ce que cela demande encore beaucoup d'efforts lorsque j'ai commencé à le faire. Je prévois donc d'enregistrer l'ensemble du processus de réalisation des exigences.

1. Présentation du contrôle d'arborescence d'antd

Les amis qui ont utilisé antd doivent savoir qu'utiliser antd consiste à coller son exemple de code, puis à le modifier en fonction de vos propres besoins et de l'API fournie par antd. Donc ici, je recherche également un exemple simple de code de contrôle d'arbre antd, quoi qu'il en soit, collez-le d'abord et voyez quel est le résultat.

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

Un simple composant en forme d'arbre est implémenté ici, mais ce composant n'a fondamentalement aucune fonction autre que la navigation, il doit donc être remodelé.
Comment ajouter des nœuds à larborescence en réaction

2. Transformez la structure du code des composants

Généralement, lorsque vous utilisez des composants antd, le plus important est d'utiliser l'API fournie par antd. Même si nous ne savons pas comment l'écrire, cela devrait être assez simple. si nous pouvons l'utiliser. En parcourant l'API du contrôle d'arborescence, j'ai constaté que le composant <tree></tree> possède un sous-composant <treenode></treenode>, qui est le plus petit composant qui constitue l’ensemble de l’unité de contrôle de l’arborescence. Donc si nous voulons implémenter des ajouts, des suppressions et des modifications, nous devons travailler dur sur ce composant <treenode></treenode>. Sur la base de cette idée, il se transforme ensuite comme suit. <tree></tree>组件有个子组件<treenode></treenode>,它就是组成整个树形控件的最小单元。所以我们如果要实现增删改的话,就要在这个<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>
            {renderTreeNodes(item.children)}
          </treenode>
        );
      }

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

    return nodeArr;
  };

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

然后就是如下的样子:
Comment ajouter des nœuds à larborescence en réaction
这里要说明的一点是<treenode></treenode>

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>
  );}
Ensuite, cela ressemble à ceci :

Insérer la description de l'image ici
Le point à noter ici est que le titre de <treenode></treenode> reçoit des données de type ReactNode, vous pouvez donc définir le style pour afficher les données en fonction de cela, comme l'ajout d'une classe d'icônes. Alors à ce stade, tout le monde devrait le savoir. L'exigence ne dit-elle pas qu'il devrait y avoir des fonctions d'ajout, de suppression et de modification ? Vous pouvez simplement utiliser ce titre pour montrer que la victoire est juste devant vous, et ensuite vous pouvez la transformer ? le code. Comment ajouter des nœuds à larborescence en réaction

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>
  );}
Maintenant, il y a trois boutons. Les fonctions spécifiques ne sont toujours pas disponibles, alors faisons-les une par une.


3. Implémentez la fonction d'ajout de nœuds

Pour ajouter des nœuds, la méthode d'implémentation consiste à transmettre la valeur clé du nœud actuel, puis à parcourir le tableau de données. Lors de la traversée du tableau pour ajouter des nœuds, cela implique. l'algorithme de requête d'objets de tableau imbriqués, qui utilise les idées de parcours en profondeur et en largeur des tableaux apprises au cours des deux semaines précédentes.
Voici le code modifié basé sur cette idée : Comment ajouter des nœuds à larborescence en réaction

  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,
      },
    ],
  },];
Cliquez sur le bouton Ajouter et un nouveau nœud par défaut apparaîtra :

3. Implémentez la fonction de nœud d'édition

Après avoir eu l'idée d'ajouter le nœud ci-dessus, l'édition ultérieure Il est plus facile d'utiliser la fonction de suppression. Seuls des extraits de code sont présentés ici et la version finale du code se trouve à la fin de l'article. Lors de la modification d'un nœud, vous devez rendre le nœud modifiable, vous devez donc utiliser une variable pour le gérer.
 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);
        }
      }
    });

4. Implémentez la fonction de suppression de nœud
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)}            
  );}
5. Code complet
rrreee recommande d'apprendre : "🎜tutoriel vidéo React🎜"🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn