title: Using React Virtualized CellMeasurer with changing data order for List and dynamic heights
body: <p>I am trying to create a chat application using React Virtualized. So far everything is working but I think think I am doing something wrong when using keyMapper and rowRenderer from the list. </p>
  
  <p>The cache is using the id to store the height in the _rowHeightCache but it seems that the heights are looked up using the index and not the id. Im not sure if I should be passing the id as the rowIndex to CellMeasurer to get the right heights or something of that nature. </p>
  
  <p>The issue is that the heights are wrong due to the changing order of the messages list so the index's don't have the proper heights and also that messages can be removed messing up the index orders. This I think should be fixed by using keyMapper to look up the heights but i must be doing it wrong.</p>
  
  <p>The following is an edited down version of how I am using it.</p>
  
  <pre><code>constructor(props) {
          this._cache = new CellMeasurerCache({
              defaultHeight: 45,
              fixedWidth: true,
              keyMapper: (index) =&gt; _.get(this.props.messageList[index], ['msgId'])
          });
      }
  
      render() {
          const props = this.filterProps(this.props),
              list = this.props.messageList,
              rowCount = list.length;
  
          return (
  
              &lt;InfiniteLoader
                  threshold={0}
                  isRowLoaded={this._isRowLoaded}
                  loadMoreRows={this._loadMoreRows}
                  rowCount={rowCount}&gt;
                  {({onRowsRendered, registerChild}) =&gt; (
                      &lt;AutoSizer&gt;
                          {({width, height}) =&gt; (
                              &lt;List
                                  ref={(ref) =&gt; {
                                      this.streamLane = ref;
                                      registerChild(ref);
                                  }}
                                  height={height}
                                  width={width}
                                  onRowsRendered={onRowsRendered}
                                  rowCount={rowCount}
                                  rowRenderer={this._rowRenderer}
                                  deferredMeasurementCache={this._cache}
                                  rowHeight={this._cache.rowHeight}
                              /&gt;
                          )}
                      &lt;/AutoSizer&gt;
                  )}
              &lt;/InfiniteLoader&gt;
         );
     }
  
      _rowRenderer({ index, key, parent, style }) {
          return (
              &lt;CellMeasurer
                  cache={this._cache}
                  columnIndex={0}
                  key={key}
                  parent={parent}
                  rowIndex={index}&gt;
                  &lt;div style={{...style}}&gt;
                      {this.props.messageList[index]}
                  &lt;/div&gt;
              &lt;/CellMeasurer&gt;
          );
      }
  
      _loadMoreRows({startIndex, stopIndex}) {
  
          return new Promise((resolve) =&gt; {
              if (!!stopIndex || !!startIndex || this.props.hasLastMessage || this.state.isPinned) {
                  return resolve();
              }
  
              this.props.loadOlder(() =&gt; resolve);
          });
      }
  
      _isRowLoaded({index}) {
          if (index === 0) return false;
          return !!this.props.messageList[index];
      }
    }
  </code></pre>
  
  <p>Any help, suggestions or criticisms would be amazing.</p>