问题描述
最近,我一直在使用react-virtualized库来渲染我的树项目视图。我遵循了文档中的示例,但是最终我遇到了一个非常奇怪的问题,即当我向下滚动时项目消失了。
https://codesandbox.io/s/bitter-snow-23vci?file=/src/App.js
解决方法
将列表虚拟化为列表的主要思想。
如果您将树状结构传递下来并像代码示例中那样渲染它
<List
....
rowCount={data.length}
/>
您无需更改rowCount值并在Node组件中保持扩展状态。
const Node = ({ data,listRef,depth }) => {
const [isExpanded,setIsExpanded] = React.useState(false);
但是随后滚动到屏幕之外时,Node元素将被破坏并重新创建,然后返回。
您需要将选择保留在Node元素之外。
喜欢
// [key]: value structure there key is id of element and value [true,false].
const rootObject = {[elementId]: true};
const App = () => {
const [visibleNodes,setVisibleNodes] = useState(rootObject)
....
<List
...
rowRenderer={({ index,style,key }) => {
return (
<Node
setVisibleNodes={setVisibleNodes}
visibleNodes={visibleNodes}
style={style}
key={key}
data={data[index]}
listRef={ref}
depth={1}
/>
);
}}
rowCount={data.length}
width={width}
/>
在Node
中const Node = ({ data,depth,setVisibleNodes,visibleNodes }) => {
const isExpanded = visibleNodes[data.id];
const handleClick = (e) => {
if (data.children.length === 0) return;
e.stopPropagation();
setVisibleNodes({...visibleNodes,[data.id]: !!isExpanded});
listRef.current.recomputeRowHeights();
listRef.current.forceUpdate();
};
return (
<div onClick={handleClick}>
{data.children.length ? (isExpanded ? "[-]" : "[+]") : ""} {data.name}
{isExpanded && (
<div style={{ marginLeft: depth * 15 }}>
{data.children.map((child,index) => (
<Node
key={index}
data={child}
listRef={listRef}
depth={depth + 1}
/>
))}
</div>
)}
</div>
);
};
我认为它可行)
但是,最好执行诸如真实列表之类的事情,并在视觉上使树的层次结构更好。这样一来,您就可以使用创建者使用的虚拟化列表