React-virtualized: scrollToIndex not working with child component

Created on 26 Jan 2018  路  5Comments  路  Source: bvaughn/react-virtualized

I have a component that renders a List and will properly scroll to the bottom of the List every time it is updated:

import React from 'react'

import { CellMeasurerCache, CellMeasurer } from 'react-virtualized'

import SpeechBubble from './SpeechBubble'
import { List, AutoSizer } from 'react-virtualized'

import './styles/Conversation.css'

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

const Conversation = ( { messages } ) => {

  const rowRenderer = ( { index, key, style, parent } ) => {
    const message = messages[ index ]
    return (
      <CellMeasurer
        cache={ cache }
        columnIndex={ 0 }
        key={ key }
        parent={ parent }
        rowIndex={ index }
      >
        <SpeechBubble
          direction={ message.direction }
          key={ key }
          style={ style }
        >
          { message.text }
        </SpeechBubble>
      </CellMeasurer>
    )
  }

  return (
    <div className="Conversation" >
      <AutoSizer>
        { ( { width, height } ) => (
          <List
            deferredMeasurementCache={ cache }
            height={ height }
            overscanRowCount={ 20 }
            rowCount={ messages.length }
            rowHeight={ cache.rowHeight }
            rowRenderer={ rowRenderer }
            scrollToAlignment="end"
            scrollToIndex={ messages.length - 1 }
            width={ width }
          />
        ) }
      </AutoSizer>
    </div>
  )
}

export default Conversation

When I merely extract the AutoSizer / List into a child component, the list still updates properly, but it no longer scrolls to the bottom when it is updated:

import React from 'react'

import { CellMeasurerCache, CellMeasurer } from 'react-virtualized'

import SpeechBubble from './SpeechBubble'

import ConversationList from './ConversationList'

import './styles/Conversation.css'

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

const Conversation = ( { messages } ) => {

  const rowRenderer = ( { index, key, style, parent } ) => {
    const message = messages[ index ]
    return (
      <CellMeasurer
        cache={ cache }
        columnIndex={ 0 }
        key={ key }
        parent={ parent }
        rowIndex={ index }
      >
        <SpeechBubble
          direction={ message.direction }
          key={ key }
          style={ style }
        >
          { message.text }
        </SpeechBubble>
      </CellMeasurer>
    )
  }

  return (
    <div className="Conversation" >
      <ConversationList
        cache={ cache }
        messages={ messages }
        rowRenderer={ rowRenderer }
      />
    </div>
  )
}

export default Conversation
import React, { Component } from 'react'

import { AutoSizer, List } from 'react-virtualized'

class ConversationList extends Component {

  render() {
    const { cache, messages, rowRenderer } = this.props
    return (
      <AutoSizer>
        { ( { width, height } ) => (
          <List
            deferredMeasurementCache={ cache }
            height={ height }
            overscanRowCount={ 20 }
            rowCount={ messages.length }
            rowHeight={ cache.rowHeight }
            rowRenderer={ rowRenderer }
            scrollToAlignment="end"
            scrollToIndex={ messages.length }
            width={ width }
          />
        ) }
      </AutoSizer>
    )
  }
}

export default ConversationList

Any ideas on why the mere extraction of a component would make a difference in whether it scrolls to the bottom or not?

Most helpful comment

@bvaughn Thanks for the response. I filed it because it appeared to be a bug, but I totally understand closing it since I didn't have a complete working repo.

Since I found a workaround, I'm not going to take the time to create a repo and dig further here. But, I definitely appreciate your time here and your great contributions to this library!

Note for future readers: I have noticed differences in behavior in this library when you merely swap between using a stateless vs. class component and also when you put the react-virtualized components in the same code block vs. extracting them into separate components. When debugging, I would highly recommend collapsing all the nested RV components into a single code block to eliminate possible issues with nesting components.

All 5 comments

Interestingly, I just noticed that if I'm already scrolled to the bottom of the component, then it will continue to scroll to the bottom as I add new elements. When I scroll up and add elements, it will append elements to the list but not scroll to the bottom. But, as soon as I start moving the scroll position, it immediately jumps to the bottom.

BTW - I'm testing it out on Chrome: Version 63.0.3239.132 (Official Build) (64-bit)

I worked around the issue by add a ref to the List and manually calling the scrollToRow() method, but I'm still curious if there is an explanation for this difference in behavior.

Hey @javidjamae,

In general, _questions_ are better directed to RV Slack or Stack Overflow, and should always include a link to a runnable example of what you're doing (rather than a snippet of code). Over time, I've found that many times the answer lies outside of the snippet of code people share and it's a big time investment going back and forth determining that if not everything is presented up front.

@bvaughn Thanks for the response. I filed it because it appeared to be a bug, but I totally understand closing it since I didn't have a complete working repo.

Since I found a workaround, I'm not going to take the time to create a repo and dig further here. But, I definitely appreciate your time here and your great contributions to this library!

Note for future readers: I have noticed differences in behavior in this library when you merely swap between using a stateless vs. class component and also when you put the react-virtualized components in the same code block vs. extracting them into separate components. When debugging, I would highly recommend collapsing all the nested RV components into a single code block to eliminate possible issues with nesting components.

Thanks for being so understanding and for leaving a summary for people who might come across this issue in the future.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hyeminHwang picture hyeminHwang  路  3Comments

athorwall picture athorwall  路  4Comments

davidychow87 picture davidychow87  路  3Comments

bee0060 picture bee0060  路  3Comments

ellatrix picture ellatrix  路  3Comments