22

I'm using react-virualized 9 with Autosizer, List, and CellMeasurer components. I need to update the row heights when the list data has changed. It appears that since the changes to support React Fiber in version 9 the only public method for CellMeasurer is now measure(). Most of the examples use the previous resetMeasurementForRow() method. The current CellMeasurer doc doesn't seem to have any info on the new public methods. Not sure if I've overlooked something but any help is appreciated.

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

<AutoSizer>
  {({ width, height }) => (
    <List
      deferredMeasurementCache={cache}
      height={height}
      ref={element => { this.list = element; }}
      rowCount={list.length}
      rowHeight={cache.rowHeight}
      rowRenderer={this.rowRenderer}
      width={width}
    />
  )}
</AutoSizer>

rowRenderer({ index, key, parent, style }) {
  return (
    <CellMeasurer
      cache={cache}
      columnIndex={0}
      key={key}
      overscanRowCount={10}
      parent={parent}
      ref={element => { this.cellMeasurer = element; }}
      rowIndex={index}
    >
      {({ measure }) => {
        this.measure = measure.bind(this);

        return <MyList index={index} data={list[index]} style={style} />;
      }}
    </CellMeasurer>
  );
}

componentWillReceiveProps(nextProps) {
  // Some change in data occurred, I'll probably use Immutable.js here
  if (this.props.list.length !== nextProps.list.length) {
    this.measure();
    this.list.recomputeRowHeights();
  }
}
noob
  • 17,131
  • 18
  • 103
  • 168
ibrin
  • 223
  • 1
  • 2
  • 5
  • can you provide `this.measure()` function content? I am trying to implement dynamic row height but my list item rows are completely different. – donquixote Mar 20 '20 at 12:34

2 Answers2

39

I need to update the row heights when the list data has changed. The current CellMeasurer doc doesn't seem to have any info on the new public methods.

Admittedly the docs could be improved, with regard to the new CellMeasurer. In this case though, you need to do 2 things in respond to your row data/sizes changing:

  1. If a specific list-item has changed size then you need to clear its cached size so it can be remeasured. You do this by calling clear(index) on CellMeasurerCache. (Pass the index of the row that's changed.)
  2. Next you'll need to let List know that its size information needs to be recalculated. You do this by calling recomputeRowHeights(index). (Pass the index of the row that's changed.)

For an example of something similar to what you're describing, check out the example Twitter-like app I built with react-virtualized. You can see the source here.

bvaughn
  • 12,062
  • 37
  • 43
  • 2
    do you have any demo code for how to use clear(index) ? – Ping Woo Aug 18 '19 at 19:50
  • @bvaughn you saved me! I was so stuck on this until I saw here i gotta clear the cache before recomputing. Thank you SO MUCH – YTG Apr 13 '21 at 19:47
0
if (this.props.list.length !== nextProps.list.length) {
  cache.clearAll();
}

This helped me! :)

Dan
  • 4,083
  • 2
  • 9
  • 26