2

i am trying to create a paginated/infinate scroll component, but the onScroll event is never fired.

does anyone know what i am doing wrong here?

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { ScrollView } from 'react-native';

class PaginatedScrollView extends Component {
    static propTypes = {
        paginationSize: PropTypes.number,
        data: PropTypes.array.isRequired,
        renderItem: PropTypes.func.isRequired
    }

    handleOnScroll (event) {
        console.log(event.nativeEvent.contentOffset.y);
    }

    render () {
        const {
            data,
            renderItem,
            paginationSize
        } = this.props;

        return (
            <ScrollView
                onScroll={e => this.handleOnScroll(e)}
                onContentSizeChange={console.log}
            >
                {data
                    .slice(1, paginationSize)
                    .map(renderItem)
                }

            </ScrollView>
        );
    }
}

export default PaginatedScrollView;

it seems onContentSizeChange is getting called but onScroll does not.

X0r0N
  • 1,816
  • 6
  • 29
  • 50

2 Answers2

3

You need to either bind handleOnScroll function in constructor or change it to arrow function

Bind handleOnScroll in constructor

  constructor(props){
       super(props);
       this.handleOnScroll = this.handleOnScroll.bind(this);
  }

OR

Change it to arrow function

 handleOnScroll = event => {
    console.log(event.nativeEvent.contentOffset.y);
}
Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162
  • success!. thanks. although i would have thought the call to the method (`onScroll={e => this.handleOnScroll(e)}`) would have handled this. – X0r0N Oct 18 '18 at 21:09
  • You are welcome. No you need to do what I have suggested in my answer. Keep in mind if you want to manually bind the function then you should always bind the function only in constructor like I did. Never bind anywhere else in the component. – Hemadri Dasari Oct 18 '18 at 21:12
  • Check this thread for detailed understanding about regular function and arrow function https://stackoverflow.com/questions/52031147/react-which-is-recommended-arrow-or-normal-function – Hemadri Dasari Oct 18 '18 at 21:15
1

While is true that you might need to bind the function (if you want to use this inside the event handler) thats not the cause you're not seeing the onScroll callback.

When using a ScrollView onScroll event handler, you also need to specify how often you want to get the scrolling information by passing an additional scrollEventThrottle props with a minimum value of 16 (to get the event every 16ms, which amounts to once for every frame in 60fps), otherwise you'll only get the first event.

Some additional considerations for what you want to do:

  • You might want to pass as the value of the onScroll prop the handler instead of creating an anonymous function every time, ex: onScroll={this.handleOnScroll}
  • To implement infinite scrolling you might be better of with a FlatList. Because the React Native Documentation says that ScrollViews are better for a small amount of items:

The ScrollView works best to present a small amount of things of a limited size. All the elements and views of a ScrollView are rendered, even if they are not currently shown on the screen. If you have a long list of more items than can fit on the screen, you should use a FlatList instead

elyalvarado
  • 1,226
  • 8
  • 13