I was playing around with their code in codesandbox.io.
This is what I came up with: https://codesandbox.io/s/loving-frog-pr1qu?file=/index.js
You'll have to create a span
node when populating the title
of your tree elements, where the span
elements will listen for a click event.
const treeData = [
{
title: <span onClick={() => expandNode("0-0")}>0-0</span>,
key: "0-0",
children: [
{
title: <span onClick={() => expandNode("0-0-0")}>0-0-0</span>,
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: <span onClick={() => expandNode("0-0-1")}>0-0-1</span>,
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: <span onClick={() => expandNode("0-1")}>0-1</span>,
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"
}
];
Then use a custom function to set the expandedKeys state and pass it as a prop to the Tree component. I tried using the filter
method on the previous state for removing keys but it kept giving me an error so I fell back to using the for
loop.
const expandNode = (key) => {
setAutoExpandParent(false);
setExpandedKeys((prev) => {
const outArr = [];
if (prev.includes(key)) {
for (let i = 0; i < prev.length; i++) {
if (prev[i] !== key) {
outArr.push(prev[i]);
}
}
return outArr;
} else {
prev.push(key);
return prev;
}
});
};
Note: I used antd's "Controlled Tree" example as the template and progressed from there.
Update
As I was using this solution for a project of mine, I found out a more robust method.
title
properties on the data array, it is possible to override the titleRender
prop on the tree component. titleRender
is available from antd v.4.5.0. span
tags as inline-block
with width and height set to 100%. This makes the entire node block (instead of just the span text) listen for the onClick
event when the tree has a prop of blockNode={true}
.for
loop and successfully used filter
method instead in the toggle expand method. This is more performant than looping. I created a custom ClickExpandableTree
component.
import React, { useState } from "react";
import { Tree } from "antd";
const ClickExpandableTree = props => {
const [expandedKeys, setExpandedKeys] = useState([]);
const [autoExpandParent, setAutoExpandParent] = useState(true);
const toggleExpandNode = key => {
setExpandedKeys(prev => {
const outArr = [...prev];
if (outArr.includes(key)) {
return outArr.filter(e => e !== key);
} else {
outArr.push(key);
return outArr;
}
});
setAutoExpandParent(false);
};
const onExpand = keys => {
setExpandedKeys(keys);
setAutoExpandParent(false);
};
return (
<Tree
onExpand={onExpand}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
titleRender={record => (
<span
key={record.key}
onClick={() => toggleExpandNode(record.key)}
style={{ display: "inline-block", width: "100%", height: "100%" }}
>
{record.title}
</span>
)}
{...props}
/>
);
};
export default ClickExpandableTree;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.