Элементы дерева исчезают при прокрутке вниз с помощью react-virtualized

#javascript #reactjs #react-virtualized

#javascript #reactjs #react-virtualized

Вопрос:

недавно я использовал react-virtualized library для отображения моего представления элементов дерева. Я последовал примеру из документов, однако в итоге у меня возникла очень странная проблема с исчезновением элементов при прокрутке вниз.

Я создал codesandbox, чтобы показать это поведение и код.

https://codesandbox.io/s/bitter-snow-23vci?file=/src/App.js

Ответ №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>
  );
};
  

Я думаю, это работает)

Но лучше делать такие вещи, как реальный список, и создавать иерархию дерева просто визуально. Таким образом, вы будете использовать список виртуализации, как это было задумано создателями)