❕ 这边tree有个坑,不知道大家有没有碰到过,如果后端给我们的tree接口是通过节点来依次获取,而不是返回给我们整个tree,那么我们在更新或者创建自节点后,重新加载数据,会出现不能进行异步操作的bug👇:
每次更新或者添加 重新加载子节点 异步加载会消失,我发现是因为重新设置了treedate,如果要整个树形结构重新加载,需要把选中节点的状态清空在设置,如果是子节点,要用组件自带的loadData函数来获取子节点下面的数据,重新设置treedate会自节点的异步加载会消失
由于没有找到文档中有操作状态的函数,这边我是使用挂载来清除状态
treeRef.current.state.expandedKeys = [];
treeRef.current.state.loadedKeys = [];
<Tree ref={treeRef}/>
下面是整体代码,清空状态需要看个人项目需求在哪边加👇
const [treeData, setTreeData] = useState();
//通过接口获取子节点数据
const onLoadData = async ({ key, children }) => {
const res = await getChildrenList(key);
setTreeData((origin) => {
console.log(origin, key, res, 'load');
return updateTreeData(
origin,
key,
res.data?.map((item) => {
return {
title: item.name,
key: item.id,
parent_id: key,
pic_count: item.pic_count,
};
}),
);
});
};
//树形结构拖拽
const onDragEnter = (info) => {
console.log(info, 'drag');
// expandedKeys, set it when controlled is needed
// setExpandedKeys(info.expandedKeys)
};
const onDrop = (info) => {
const dropKey = info.node.key;
const dragKey = info.dragNode.key;
const dropPos = info.node.pos.split('-');
const dropPosition =
info.dropPosition - Number(dropPos[dropPos.length - 1]);
const loop = (data, key, callback) => {
for (let i = 0; i < data.length; i++) {
if (data[i].key === key) {
return callback(data[i], i, data);
}
if (data[i].children) {
loop(data[i].children, key, callback);
}
}
};
const data = [...treeData];
// Find dragObject
let dragObj;
loop(data, dragKey, (item, index, arr) => {
arr.splice(index, 1);
dragObj = item;
});
if (!info.dropToGap) {
// Drop on the content
loop(data, dropKey, (item) => {
item.children = item.children || [];
// where to insert. New item was inserted to the start of the array in this example, but can be anywhere
item.children.unshift(dragObj);
});
} else if (
(info.node.props.children || []).length > 0 &&
// Has children
info.node.props.expanded &&
// Is expanded
dropPosition === 1 // On the bottom gap
) {
loop(data, dropKey, (item) => {
item.children = item.children || [];
// where to insert. New item was inserted to the start of the array in this example, but can be anywhere
item.children.unshift(dragObj);
// in previous version, we use item.children.push(dragObj) to insert the
// item to the tail of the children
});
} else {
let ar = [];
let i;
loop(data, dropKey, (_item, index, arr) => {
ar = arr;
i = index;
});
if (dropPosition === -1) {
ar.splice(i, 0, dragObj);
} else {
ar.splice(i + 1, 0, dragObj);
}
}
console.log(data, 'drop');
setTreeData(data);
};
<Tree
//获取子节点数据
loadData={onLoadData}
treeData={treeData}
// expandedKeys={expandedKeys}
ref={treeRef}
//选择节点要用到
// onSelect={onSelect}
//每次点击节点进行函数操作
onSelect={([key], ev) => {
setCurrentPd(ev.node);
setPdPos(ev.node.pos);
}}
//树形结构的拖拽
onDragEnter={onDragEnter}
onDrop={onDrop}
blockNode={true}
draggable={ifDrop}
//对子节点进行自定义渲染
titleRender={(e) => {
return (
<div
style={{ display: 'flex', justifyContent: 'space-between' }}
>
</div>
);
}}
/>