scrollToRow() on List component with WindowScroller not working

19 views Asked by At

Background

I'm using an implementation of react-virtualized with:

  • WindowScroller to allow scrolling to happen on the page (not within a container), and an onResize event handler to clear the CellMeasurerCache (for a responsive layout)
  • AutoSizer for calculating automatic an width (for a responsive layout)
  • List to display basic content in one column (an image and text on every row)
  • CellMeasurer with an <img /> onLoad to calculate the dynamic height of each row (they will all be different depending on what image/text is on that row),

My reason for using react-virtualized is because the core of my site is an infinitely scrolling vertical list with large images, and the page will get very large very quickly if new elements were just appended to the bottom as you scrolled.

Issue

I am attempting to call the List public method scrollToRow() so when you click on a button (will eventually be a nav link), you're scrolled to a particular row on the page. However it doesn't appear to be working. (I'm very new to react-virtualized.)

Code

import { useRef } from "react";
import {
  CellMeasurerCache,
  CellMeasurer,
  WindowScroller,
  AutoSizer,
  List,
} from "react-virtualized";

import "./styles.css";

const dummydata = [
  // ...
];

const cellMeasurerCache = new CellMeasurerCache({
  defaultHeight: 50,
});

function rowRenderer({ key, index, isScrolling, isVisible, style, parent }) {
  return (
    <CellMeasurer
      cache={cellMeasurerCache}
      columnIndex={0}
      key={key}
      parent={parent}
      rowIndex={index}
    >
      {({ measure, registerChild }) => (
        <div
          ref={registerChild}
          style={style}
          data-key={key}
          data-is-visible={isVisible}
        >
          <div>
            {dummydata[index].id} -- {dummydata[index].text}
          </div>
          <img
            className="img"
            onLoad={measure}
            src={dummydata[index].img}
            alt={dummydata[index].text}
          />
        </div>
      )}
    </CellMeasurer>
  );
}

export default function App() {
  const listRef = useRef();

  function goToRow(index, e) {
    // NOT WORKING
    listRef.current.scrollToRow(index);
  }

  function clearCellMeasurerCache() {
    cellMeasurerCache.clearAll();
  }

  return (
    <div className="App">
      <h2>PhotoList</h2>
      <div style={{ paddingBottom: "1em" }}>
        <button onClick={goToRow.bind(this, 9)}>SCROLL TO ROW 10</button>
      </div>
      <WindowScroller onResize={clearCellMeasurerCache}>
        {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (
          <AutoSizer disableHeight>
            {({ width }) => (
              <div ref={registerChild}>
                <List
                  ref={listRef}
                  width={width}
                  height={height}
                  autoHeight
                  rowCount={dummydata.length}
                  deferredMeasurementCache={cellMeasurerCache}
                  rowHeight={cellMeasurerCache.rowHeight}
                  rowRenderer={rowRenderer}
                  isScrolling={isScrolling}
                  onScroll={onChildScroll}
                  scrollTop={scrollTop}
                />
              </div>
            )}
          </AutoSizer>
        )}
      </WindowScroller>
      <div>End</div>
    </div>
  );
}

See: CodeSandbox


Thanks in advance for any help you can provide!

0

There are 0 answers