Preface: the world is very few, people tu tu, each way programming, only my front end. Always keen on the front end, but only at the beginning of the door, looking for the way to improve failed, so can only record the problems encountered in the work through the way of narration, but to express clear, improve their understanding of the front end knowledge. Tree structure data in the work often encountered, today write an article to record the operation of tree shape data experience.

The core content of the article is divided into three parts

  • First, flat data is converted to tree data
  • In both cases, tree data is converted to flat data
  • The latter (goal) : A silky search Tree with ANTD and reactJs

Flat data to tree data

  • First, write a random piece of relevant data:

const data = [
  { name: "马云".key: 1 },
  { name: "Front End Technical specialist".key: 3.parent: 2 },
  { name: "Chief scientist".key: 2.parent: 1 },
  { name: "Front-end Architect".key: 4.parent: 3 },
  { name: "Front End Engineer".key: 5.parent: 4 },
  { name: "Front-end newbie".key: 6.parent: 5 },
  { name: "Little white front".key: 7.parent: 6 },
  { name: Father-in-law ma.key: 8 },
  { name: "QQ".key: 9.parent: 8 },
  { name: "WeChat".key: 10.parent: 8 },
  { name: Honor of Kings.key: 11.parent: 8 },
  { name: "绝地求生".key: 12.parent: 8 },
  { name: "QQ member".key: 13.parent: 9 },
  { name: "QQ space".key: 14.parent: 9 },
  { name: "QQ wallet".key: 15.parent: 9 },
  { name: "Desert Map".key: 16.parent: 12 },
  { name: "Public Account".key: 17.parent: 10 },
  { name: "Group".key: 18.parent: 10 },
  { name: "Applets".key: 19.parent: 10 },
  { name: "Mulan".key: 20.parent: 11 },
  { name: "Mi month".key: 21.parent: 11 },
  { name: Marco Polo.key: 22.parent: 11},];Copy the code
  • The data I wrote are the top fathers of Ma Yun and Ma Huateng, and according to the rank criteria of Ali, what we hope to get is this:

  • Based on huateng’s father-in-law’s relationship with his money-sucking empire, we hope to get the following results:

  • So the question is, how do you get this hierarchical data? Let’s take one by one; Key in the data represents the unique identity of the current data, and parent represents its parent. So, what we need to do is to iterate through the data array and generate the tree data according to the parent and key relationship. Here we use children to hold the child data. Don’t talk too much, just get to the talent.
// Encapsulate the getTree method to convert the array to a tree.

import { cloneDeep } from "lodash";// Add cloneDeep to the lodash library

const getTree = (data) = > {

  const temp = cloneDeep(data);// Clone a copy of the foreign data in case the following processing modifies the data itself
  const parents = temp.filter((item) = >! item.parent);// Filter out the highest parent set
  const children = temp.filter((item) = > item.parent);// Filter out the child node
  
  // Add the child to the children property of node by looking for the node corresponding to the child's parent in Temp.
  children.map((item) = > {
    const node = temp.find((el) = > el.key === item.parent);
    node && (node.children ? node.children.push(item) : node.children = [item]);
  });
  return parents;// return the assembled data.
};
Copy the code
  • To wrap the geTree method, call:
const tree=getTree(data);
console.log(tree);
Copy the code
  • The printed result is as follows:

  • Huateng’s father-in-law was as follows:

  • Array to tree content ends here, confused friends can leave a comment discussion.

Tree Data is converted to flat data

  • Array to tree can do, then the next is tree to array.
  • Define a random piece of data:
const treeData = [
  {
    title: "Tai chi".key: 1.children: [{title: "Two instrument".key: 2.parent: 1.children: [{title: "Old Yang".key: 3.parent: 2.children: [{ title: "Originality".key: 7.parent: 3}],}, {title: "Little sun".key: 4.parent: 2.children: [{title: "Xun hexagrams".key: 9.parent: 4 },
              { title: "The eight diagrams".key: 10.parent: 4 },
              { title: "From the hexagrams".key: 11.parent: 4},],}, {title: "The old Yin".key: 5.parent: 2.children: [{ title: "He sticks".key: 8.parent: 5}],}, {title: "Little Yin".key: 6.parent: 2.children: [{title: "Gen hexagrams".key: 12.parent: 6 },
              { title: "Kangua".key: 13.parent: 6 },
              { title: "Shake hexagrams".key: 14.parent: 6},],},],},],},},];Copy the code
  • The Master said, “If you give me a few years and fifty years to learn, I will be able to do nothing too serious.” It can be seen that Confucius praised the I Ching highly. The above data is the evolution process from Taiji to bagua in the BOOK of Changes, which is very wonderful. It can be said that all the universe is in this evolution law: Taiji – “Two Yi -” “Four images -” “the eight diagrams. What we need to do is convert this tree data into a flat structure. Don’t talk too much, just get to the talent.
const getFlatData=(data) = >{
    const flatData=[];
    data.map(item= >{
      // Deconstruct the current item, remove children from item, and add pure node (single data without children) to flatData. If children exist, the getFlatData method is recursively executed until all are added.
        const{children,... node}=item flatData.push(node); children&&flagData.push(... getFlatData(children)); })return flatData;
};
Copy the code
  • Now that the method is written, execute the code:
  console.log(getFlatData(treeData));
Copy the code
  • The effect is as follows:

  • Tree data flattening ends here, and finally let’s implement an interesting feature called search tree.

Goal: AntD +ReactJs to achieve a silky search tree

  • First, to implement the search box and tree, we expand all tree nodes by default, the effect is as follows:

  • When searching, we want to show only the search term containing the keyword and its parent. Look at the picture:
  • When we search “flowers and trees” :

  • When we search for “flower” :

  • In other words, when we search, we’re going to take apart the superfluous parts of the original tree structure, leaving only what we need. How do you do that? There are two steps: first, find the item containing the keyword and its parent. Step 2: Generate a real-time tree structure using the getTree method we encapsulated earlier. So let’s do that.
  • First, modify the previously encapsulated getFlatData method to add a parents attribute to the tree’s children, which identifies all the parents of the current child. As follows:
const getFlatData = (data) = > {
  const flagData = [];
  data.map((item) = > {
    const{ children, ... node } = item; flagData.push(node); +----------- children && children.map((el) = > {
        el.parents = (item.parents ? item.parents + "," : "") + item.key;
      }); // Sets all the parents of the current element.+----------- children && flagData.push(... getFlatData(children)); });return flagData;
};
Copy the code
  • I just added one line of code to the dotted line. The effect is as follows:

  • The processed data adds the parents property, which identifies all the parent keys of the current element.

  • Next, start interface programming:

import React, { useRef, useState } from "react";
import { cloneDeep } from "lodash";
import { Tree, Input } from "antd";
import {
  DownOutlined,
} from "@ant-design/icons";

const SearchTree = () = > {
  const [expands, setExpands] = useState(() = > data.map((item) = > item.key));// Initializes the tree expansion key
  
  const flatData = useRef({});// the ref variable is used to hold the original tree data and the flattened structure data processed by the enhanced getFlatData.
  
  const [treeData, setTreeData] = useState(() = > {// Initialize tree data.
    const tree = getTree(data);
    flatData.current.flat = getFlatData(tree);// Save the flattened structure data processed by the enhanced getFlatData.
    flatData.current.tree = tree;// Save the initial tree data
    return tree;
  });

  const handleSearch = (e) = > {};

  return (
    <div
      style={{
        width: 399.height: 399.display: "flex",
        flexDirection: "column,}} ">
      <Input onChange={handleSearch} />
      <Tree
        showIcon
        defaultExpandAll
        expandedKeys={expands}
        switcherIcon={<DownOutlined />}
        treeData={treeData}
      />
    </div>
  );
};

export default SearchTree;
Copy the code
  • As shown in the picture, the interface is very simple, only one input box and a Tree. Initialize three states. See the illustration for the three states. Our focus is on implementing the handleSearch method.

  • The handleSearch method is implemented as follows:

const handleSearch = (e) = > {
try {
  constv = e? .target? .value? .trim();if(! v? .length) {// If the search content is empty, initialize the tree, and expand it all by default

    setExpands(data.map((item) = > item.key));
    setTreeData([...flatData.current.tree]);

  } else {// Search content is not empty, get the search term and its parent, real-time generation tree

    const keys = flatData.current.flat.filter((item) = >item? .title? .includes(v) );// Get the searched item

    if(! keys? .length) {// If you search for "Mulan baby", you will find nothing
      setExpands([]);
      setTreeData([]);
      return;
    }

    // The following logic handles the case where keys are not empty

    const expandsTemp = [];// The key to expand
    const list = [];// Store the search term and its parent arraykeys? .map((item) = > {
      constdata = item.parents? .split(",").filter(Boolean);// Split the parents property to get all the parents of the current item
      data &&
        data.map((el) = > {
          if (expandsTemp.every((_el) = >_el ! == el)) { expandsTemp.push(el);// This check ensures that the key value in expandsTemp does not duplicate}}); list.push(item); }); expandsTemp.map((item) = > {
      if (list.every((el) = >el.key? .toString() ! == item)) {// The key of the element in the list should also be unique.
        const node = flatData.current.flat.find(
          (el) = > el.key?.toString() === item
        );
        node && list.push(node);
      }
    });// Iterate through expandsTemp to add the parent element of the search item to the list.

    const tempTree = getTree(list);// Assemble the tree from the list
    setExpands([...expandsTemp.map((item) = > Number(item))]);// Map converts keys in expandsTemp to numbers.
    setTreeData([...tempTree]);// Set the real-time tree}}catch (e) {}
};
Copy the code
  • The description of the search method is shown in the figure. The difficulty lies in finding all the parents through the parents attribute of the tree child element, adding them to an array without repeating, and finally assembling the tree structure data.

The epilogue

  • That’s all for now, let’s be happy and dance!