#javascript #reactjs #react-virtualized
#javascript #reactjs #react-virtualized
Вопрос:
недавно я использовал react-virtualized library для отображения моего представления элементов дерева. Я последовал примеру из документов, однако в итоге у меня возникла очень странная проблема с исчезновением элементов при прокрутке вниз.
Я создал codesandbox, чтобы показать это поведение и код.
Ответ №1:
Основная идея виртуального списка — отображать его как список.
Если вы передадите древовидную структуру и отобразите ее, как в вашем примере кода
<List
....
rowCount={data.length}
/>
Вы не меняете значение rowCount и сохраняете расширенное состояние в своем компоненте узла.
const Node = ({ data, listRef, depth }) => {
const [isExpanded, setIsExpanded] = React.useState(false);
Но затем вы прокручиваете экран, ваш элемент узла будет уничтожен и воссоздан заново, после чего вы вернетесь.
Вам нужно сохранить ваши выборки за пределами элемента 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}
/>
И в узле
const Node = ({ data, listRef, 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 amp;amp; (
<div style={{ marginLeft: depth * 15 }}>
{data.children.map((child, index) => (
<Node
key={index}
data={child}
listRef={listRef}
depth={depth 1}
/>
))}
</div>
)}
</div>
);
};
Я думаю, это работает)
Но лучше делать такие вещи, как реальный список, и создавать иерархию дерева просто визуально. Таким образом, вы будете использовать список виртуализации, как это было задумано создателями)