有一个树状结构,应该对其进行扩展,以使所有选中的子级都可见。
这是代码:
const { data } = useGetData(); // react-query hook that gets data from an endpoint
接下来,有一个函数可以返回一个带有节点父节点的数组:
const getAllParents = (key: string, parentNodes: string[]) => {
Object.keys(data).forEach((itemKey: string) => {
if (
data[itemKey]?.hasChildren &&
data[itemKey].children?.filter((child: string) => child === key).length
) {
parentNodes.push(itemKey);
getAllParents(itemKey, parentNodes);
}
});
return parentNodes;
};
这里是useEffect,它应该在树加载后运行一次:
useEffect(() => {
let allParents: string[] = [];
let uniqueParents: string[] = [];
selectedItems.forEach((item) => {
const itemParents: string[] = getAllParents(item, []);
allParents = [...allParents, ...itemParents];
uniqueParents = [...new Set(allParents)];
});
setExpandedItems(uniqueParents);
}, [getAllParents, selectedItems, uniqueParents]);
问题是这个useEffect持续运行。有一种方法可以阻止它这样做,从依赖数组中删除getAllParents
。
但这样做会显示警告:React Hook useEffect缺少依赖项:"getAllParents"。请将其包括在内或删除依赖项数组
无论如何,它仍然不能正常工作,它应该只在加载树时运行一次。有什么办法吗?
添加USECALLBACK后的更新:
我已经将getAllParents
封装在一个useCallback:中
const getAllParents = useCallback((key: string, parentNodes: string[]) => { ... }, [data]);
使用效果:
如果依赖数组为空(
[]
(:它根本不运行,则树不会展开[getAllParents, selectedItems]
:它将永远运行[ selectedItems]
:它似乎工作得很好,但也有关于缺少依赖项的相同警告。
如果getAllParents
在React组件内部定义,useEffect
将在每次渲染时将其视为一个新函数(通过引用进行比较(。尝试用useCallback
包装它,以避免为每个渲染创建新函数
您可以尝试用React.useCallback
钩子包装getAllParents
函数