0

I am rendering a long list using the react-virtualized library. everything is working fine, but when I sort the data using the javascript sort method then the height of the divs doesn't change when the data changes. how can I change the height also when the data changes? I have been searching for a solution for 3 days but all the solutions are in the functional component.

here is my code

export default function App() {
  const cache = React.useRef(
    new CellMeasurerCache({
      fixedWidth: true,
      defaultHeight: 100,
    })
  );
  const [people, setPeople] = React.useState([]);

  React.useEffect(() => {
    setPeople(
      [...Array(1000).keys()].map((key) => {
        return {
          id: key,
          name: `${faker.name.firstName()} ${faker.name.lastName()}`,
          bio: faker.lorem.lines(Math.random() * 100),
        };
      })
    );
  }, []);



  const ascending = (index) => {
    const filter = [...people].sort((a, b) => a.name.localeCompare(b.name))
    setPeople(filter)
  }
  const decending = () => {
    const filter = [...people].sort((a, b) => b.name.localeCompare(a.name))
    setPeople(filter)
  }


  return (
    <div>
      <button onClick={ascending}>ascending</button>
      <button onClick={decending}>decending</button>

      <div style={{ width: "100%", height: "100vh" }}>
        <AutoSizer>
          {({ width, height }) => (
            <List
              width={width}
              height={height}
              rowHeight={cache.current.rowHeight}
              deferredMeasurementCache={cache.current}
              rowCount={people.length}
              rowRenderer={({ key, index, style, parent }) => {
                const person = people[index];

                return (
                  <CellMeasurer
                    key={key}
                    cache={cache.current}
                    parent={parent}
                    columnIndex={0}
                    rowIndex={index}
                  >
                    <div style={style}>
                      <h2>{person.name}</h2>
                      <p>{person.bio}</p>
                    </div>
                  </CellMeasurer>
                );
              }}
            />
          )}
        </AutoSizer>
      </div>
    </div>
  );
}
Sajib Hossain
  • 81
  • 2
  • 8

1 Answers1

1

After changing the order, you need to clear the cache:

  const ascending = (index) => {
    const filter = [...people].sort((a, b) => a.name.localeCompare(b.name));
    setPeople(filter);
    cache.current.clearAll();
  };

See: Dynamic row heights with react-virtualized and new CellMeasurer

Working snippet - https://codesandbox.io/s/react-virtualized-demo-forked-wwgu16

Rayon
  • 36,219
  • 4
  • 49
  • 76
Roy Schut
  • 136
  • 4