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?
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.
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.