Common tree components may include custom functions such as editing and deleting. For example:

Unlike elementUI trees, Antd trees do not directly provide render-content to customize node content. Instead, you can only pass a custom ReactNode to the title to render the content of each node.

The code might look like this:

                <Tree
                    showLine
                >
                    <TreeNode title={<div>. The node name<span>The editor</span>
                                <span>delete</span>
                            </div>} key="0-0">
                        <TreeNode title={<div>. The node name<span>The editor</span>
                                <span>delete</span>
                            </div>} key="0-0-0">
                            <TreeNode title={<div>. The node name<span>The editor</span>
                                <span>delete</span>
                            </div>} key="0-0-0-0" />
                            <TreeNode title="leaf" key="0-0-0-1" />
                        </TreeNode>
                    </TreeNode>
                </Tree>
Copy the code

You might say that the title section can be detached and encapsulated as a component. Yes, when I removed the title part of the code into a component, I wondered if I could replace the entire TreeNode with my own TreeNode, something like this:

                <Tree
                    showLine
                >
                    <TreeN title="parent 1" key="0-0">
                        <TreeN title="parent 1-0" key="0-0-0">
                            <TreeN title='leaf' key="0-0-0-0" />
                            <TreeN title="leaf" key="0-0-0-1" />
                        </Tree>
                    </TreeN>
                </Tree>
Copy the code

TreeN function inside:

.// Omit some code
    const{ title, ... rest } = props;return (
        <TreeNode 
            title={
                <div className={treeNode}>
                    <span>{title}</span>
                    <span className={deleteBtn}>delete</span>
                    <span className={edit}>The editor</span>
                </div>} {... rest} />
    );
Copy the code

At this point, however, the console reported an error:

Tree only accept TreeNode as children.
// The Tree component only accepts TreeNode components as child components
Copy the code

All Antd components are based on RC-XXX and Tree is based on RC-Tree. Do a little googling, and there are people in similar situations, even if they don’t find a solution:

Tree component Warning exception recursive implementation of deep Tree

Looking at the compiled code, there is a function like this:

function warnOnlyTreeNode() {
  if (onlyTreeNodeWarned) return;
  onlyTreeNodeWarned = true;
  (0, _warning.default)(false.'Tree only accept TreeNode as children.');
}
Copy the code

So how does RC-Tree do child component type validation? A component is just a function, so I looked at Treenode. prototype and found that its constructor has a property: isTreeNode with a value of 1.

function isTreeNode(node) {
  return node && node.type && node.type.isTreeNode;
}

function getNodeChildren(children) {
  return (0, _toArray.default)(children).filter(isTreeNode);
}
Copy the code

Rc-tree filters out all istreenodes that are not true, so if we add this attribute and assign it to 1, we can make rC-Tree think that this is the TreeNode it wants.

import React from 'react'; import { Tree } from 'antd'; import { treeNode, edit, deleteBtn } from './typeTree.less'; const { TreeNode: AntdTreeNode } = Tree; export default function TreeNode(props) { const { title, ... rest } = props; Return (<AntdTreeNode title={<div className={treeNode}> <span>{title}</span> <span className={deleteBtn}> Delete </span> <span className={edit}> Edit </span> </div>} {... rest} /> ); } TreeNode.isTreeNode = 1;Copy the code

At this point, the component is rendered normally. This encapsulation feels a bit redundant, but for those of you who are as curious as I am