useVirtualizedList.tsx 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. import type {DependencyList, RefObject} from 'react';
  2. import {useCallback, useEffect, useMemo} from 'react';
  3. import type {CellMeasurerCacheParams, List} from 'react-virtualized';
  4. import {CellMeasurerCache} from 'react-virtualized';
  5. type Opts = {
  6. cellMeasurer: CellMeasurerCacheParams;
  7. deps: DependencyList;
  8. ref: RefObject<List>;
  9. };
  10. function useVirtualizedList({cellMeasurer, deps, ref}: Opts) {
  11. const cache = useMemo(() => new CellMeasurerCache(cellMeasurer), [cellMeasurer]);
  12. const updateList = useCallback(() => {
  13. cache.clearAll();
  14. ref.current?.forceUpdateGrid();
  15. }, [cache, ref]);
  16. // Restart cache when items changes
  17. // XXX: this has potential to break the UI, especially with dynamic content
  18. // in lists (e.g. ObjectInspector). Consider removing this as deps can easily
  19. // be forgotten to be memoized.
  20. //
  21. // The reason for high potential to break UI: updateList clears the cache, so
  22. // any cells that were expanded but scrolled out of view will have their
  23. // cached heights reset while they re-render expanded.
  24. useEffect(() => {
  25. updateList();
  26. }, [updateList, deps]);
  27. return {
  28. cache,
  29. updateList,
  30. };
  31. }
  32. export default useVirtualizedList;