4

When attempting to scrollToIndex the screen goes blank.

Here's a codesandbox that reproduces the problem. Just type 100 in the input box on top and click the "scroll to row" button. https://codesandbox.io/s/zr2r2wp1x

It's a somewhat complicated view - it uses InfiniteLoader, WindowScroller, Autosizer, CellMeasurer, CellMeasurerCache and List.

Here's the code:

import React, { Component } from 'react';
import {
  AutoSizer,
  CellMeasurer,
  CellMeasurerCache,
  InfiniteLoader,
  List,
  WindowScroller
} from 'react-virtualized';


const cache = new CellMeasurerCache({
  fixedWidth: true,
  defaultHeight: 100
});

class Hello extends Component {
  constructor(props) {
    super(props);
    this.state = {
      scrollToIndex: undefined
    }
    this.list = [];
    this.makeList = this.makeList.bind(this);
    this.makeList();
    this.handleClick = this.handleClick.bind(this);
  }

  makeList() {
    for (let i = 0; i < 200; i++) {
      this.list.push("yo");
    }
  }


  handleClick() {
    this.setState({
      scrollToIndex:this.inputRow.value
    })
  }

  isRowLoaded({ index }) {
    return !!this.list[index];
  }

  loadMoreRows({ startIndex, stopIndex }) {
    this.makeList();
  }

  rowRenderer({ index, isScrolling, isVisible, key, parent, style }) {
    if (isScrolling) {
      return null;
    }

    if (isVisible) {
      return (
        <CellMeasurer
          key={key}
          cache={cache}
          parent={parent}
          columnIndex={0}
          rowIndex={index}
        >
          <div style={style}>
            this is row: {index}
          </div>
        </CellMeasurer>
      );
    }
    return null;
  }


  render() {

    if (this.list.length === 0) {
      return <div>No data available.</div>;
    }

    const scrollToIndex = this.state.scrollToIndex;

    return (
      <div>
        <div>
          <input
            type="number"
            ref={(input) => { this.inputRow = input; }} />
          <input
            type="button"
            value="Scroll To Row"
            onClick={this.handleClick}
          />
        </div>
        <InfiniteLoader
          isRowLoaded={isRowLoaded => this.isRowLoaded(isRowLoaded)}
          loadMoreRows={loadMoreRows => this.loadMoreRows(loadMoreRows)}
          rowCount={10000}
          threshold={1}
        >
          {({ onRowsRendered, registerChild }) => (
            <WindowScroller>
              {({ height, isScrolling, onChildScroll, scrollTop }) => (
                <AutoSizer disableHeight>
                  {({ width }) => {
                    console.log("scroll to index", scrollToIndex)
                    return (
                      <List
                        autoHeight
                        height={height}
                        onRowsRendered={onRowsRendered}
                        ref={registerChild}
                        width={width}
                        rowCount={this.list.length}
                        rowHeight={cache.rowHeight}
                        rowRenderer={rowRenderer => this.rowRenderer(rowRenderer)}
                        scrollTop={scrollTop}
                        deferredMeasurementCache={cache}
                        style={{ paddingLeft: '0', paddingRight: '0' }}
                        scrollToAlignment="start"
                        scrollToIndex={scrollToIndex}
                      />
                    )
                  }}
                </AutoSizer>
              )}
            </WindowScroller>
          )}
        </InfiniteLoader>
      </div>
    );
  }
}

export default Hello;
Bob Glass
  • 465
  • 3
  • 12

1 Answers1

9

Here's an updated CodeSandbox displaying how to accomplish your desired behavior. I had to fix numerous issues with your starter code to get the example to work properly - the short answer is you were missing passing WindowScroller's render prop onChildScroll to the List component's onScroll prop. This setup will allow both the components to communicate with each other to effectively update the list properly.

Alex Mejias
  • 150
  • 6
  • 2
    Thank you Alex. I know I'm not supposed to use this area to thank people - but I'm doing it anyway - this was really helpful. – Bob Glass Mar 28 '18 at 18:46