React Native ListView scrollToEnd it doesn't work
Asked Answered
S

6

14

I use the ListView's scrollToEnd, but it doesn't work, but it worked for scrollTo. What should I do to deal with it.

enter image description here

enter image description here

Stratum answered 18/2, 2017 at 9:17 Comment(5)
I'm not sure this would work since the ListView doesn't have to render all elements when the view is mounted. There's also no way of knowing when the ListView is done with rendering all the elements. AFAIK the scrollToEnd method can be used with a button.Dorsman
Are you getting an error or is it just not doing anything?Oilstone
Also, Android or iOS?Oilstone
@user1221780 no,I have no error about it,It is running on iOS simulatorStratum
@Dorsman I have a try,It worked by used with a button,but I want to let the ListView scroll to the end at the beginningStratum
H
20

There is a workaround, wrap it in a setTimeout like so:

componentDidMount() {
  setTimeout(() => {
    this.refs.dateList.scrollToEnd();
  }, 50);
}
Humidity answered 22/9, 2017 at 17:43 Comment(4)
This is valid, but whyHarvest
Sorry, I don't remember where I got this workaround, but i can say I've spent hours struggling with this bug...Humidity
It's bad practice to use setTimeoutAbject
It'll just be because rendering takes time. Use onLayout with a bound method which scrolls to end: e.g. scrollToBottom() { this.refs.myView.scrollToEnd() } <List onLayout={this.scrollToBottom}>Gourd
D
16

Try this:

<ListView
    ref={ ( ref ) => this.scrollView = ref }
    onContentSizeChange={ () => {        
        this.scrollView.scrollToEnd( { animated: false } )
    } } >
</ListView>

document

Duplicity answered 26/9, 2017 at 7:46 Comment(0)
A
1

For functional components, the equivalent is using useEffect like so:

useEffect(()=>{
    setTimeout(ref?.current.scrollToEnd());
},[yourArrayData])

Note, you don't need to set a duration for the setTimeout, this is because of Macrotasks in JavaScript, https://javascript.info/event-loop if you want to find out more

Arawakan answered 20/5, 2023 at 7:33 Comment(2)
Note, with this solution, yourArrayData will cause the useEffect to call if it changes (if it in state) or has perceived to have changed since React does not run a deep check on objects in a dependency array link, this answer is still a viable solutionIllustrator
Yea I place the yourArrayData in the dependency array because it is equivalent to this other solution https://mcmap.net/q/795474/-react-native-listview-scrolltoend-it-doesn-39-t-work Use an empty array if you want this other equivalent solution https://mcmap.net/q/795474/-react-native-listview-scrolltoend-it-doesn-39-t-workArawakan
G
0

Rendering takes time so setTimeout() before scrolling to end will work. You can, however, use the onLayout() method.

export default MyComponent extends React.Component {
  constructor(props) {
    super(props)

    this.scrollToBottom = this.scrollToBottom.bind(this)
  }

  scrollToBottom() {
    this.refs.myView.scrollToEnd()
  }

  render() {
    return {
      <ListView
           onLayout={this.scrollToBottom}
           ref='myView'
           ...
      />
   }
 }

Note: ListView is now deprecated.

Gourd answered 27/3, 2019 at 17:18 Comment(0)
M
0

This this worked for me.

<Content ref={c => (this.contentComponent = c)}>
....Any code
</Content >

This allows you to to use the scrollToPosition(0) function like

this.contentComponent._root.scrollToPosition(0);
Megaphone answered 15/11, 2019 at 8:3 Comment(0)
F
0

I don't think it's good that the top answer is suggesting using a setTimeout, which sort of goes against React's design.

Imo, the best way to handle this (and what worked for me):

  1. Create and set a ref for the scrollable container
  2. Have the onLayout() method on the List element itself trigger the .scrollToBottom() method on the scrollable container ref.
const scrollContainer = useRef();

const scrollToEnd = () => {
  chatContainer.current.scrollToEnd();
}

<ScrollView ref={scrollContainer}>
  <FlatList onLayout={scrollToEnd}>
  </Flatlist>
<ScrollView>
Figureground answered 21/3 at 2:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.