【发布时间】:2020-10-16 13:16:32
【问题描述】:
【问题讨论】:
【问题讨论】:
我在 codesandbox.io 中玩弄他们的代码。
这是我想出的:https://codesandbox.io/s/loving-frog-pr1qu?file=/index.js
在填充树元素的title 时,您必须创建一个span 节点,其中span 元素将侦听点击事件。
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"
}
];
然后使用自定义函数设置expandedKeys 状态并将其作为prop 传递给Tree 组件。我尝试在之前的状态下使用filter 方法来删除键,但它一直给我一个错误,所以我回退到使用for 循环。
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;
}
});
};
注意:我使用了 antd 的“受控树”示例作为模板,并从那里进行了改进。
更新
当我将这个解决方案用于我的一个项目时,我发现了一种更强大的方法。
titleRender 属性,而不是单独覆盖数据数组上的title 属性。 titleRender 可从 antd v.4.5.0 获得。span 标签设置为inline-block,宽度和高度设置为100%。当树的 prop 为 blockNode={true} 时,这会使整个节点块(而不仅仅是 span 文本)侦听 onClick 事件。for 循环并成功地在切换扩展方法中使用filter 方法。这比循环更高效。我创建了一个自定义的ClickExpandableTree 组件。
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;
【讨论】: