简体   繁体   中英

Tree items dissapearing on scroll down with react-virtualized

recently I have been using react-virtualized library to render my tree item view. I have followed example from the docs however I end up having very strange problem with items disappearing when I scroll down.

I have created codesandbox to show this behaviour and code.

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

Main idea of virtualized list to render it as a list.

If you pass down tree like structure and render it like in your code sample

<List
 ....
            rowCount={data.length}
          />

You don't change rowCount value and keep expanded state in your Node component.

const Node = ({ data, listRef, depth }) => {
  const [isExpanded, setIsExpanded] = React.useState(false);

But then you scroll out of screen your Node element will be destroyed and recreated then you return.

You need to keep your selections outside of Node element.

like

// [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}
          />

And in Node

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 && (
        <div style={{ marginLeft: depth * 15 }}>
          {data.children.map((child, index) => (
            <Node
              key={index}
              data={child}
              listRef={listRef}
              depth={depth + 1}
            />
          ))}
        </div>
      )}
    </div>
  );
};

I think it works)

But it's better to do such things like real list and make tree hierarchy just visually. By that way you'll use Virtualisation List as it was purposed by creators)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM