React native infinite scroll with flatlist

后端 未结 3 1260
鱼传尺愫
鱼传尺愫 2020-12-04 01:45

I followed this tutorial https://www.youtube.com/watch?v=rY0braBBlgw When I scroll down it sends the request then it gets stuck in a loop and just requests and requests. I t

相关标签:
3条回答
  • 2020-12-04 02:28

    I'm not sure if this is exactly what you're looking for, but the code I've left below allows you to continue scrolling through a fixed set of data props. When you reach the last index, it basically wraps around to the beginning. I've achieved this by appending a copy of the first element of the supplied data to the end of the FlatList; when the user scrolls this into view, we can safely reset the scroll offset.

    import React, { Component } from 'react';
    import { FlatList } from 'react-native';
    
    export default class InfiniteFlatList extends Component {
    
      constructor(props) {
        super(props);
        this.state = {
        };
        this._flatList = null;
      }
    
      getWrappableData = (data) => {
        return [...data, data[0]];
      }
    
      render = () => (
        <FlatList
          { ...this.props }
          ref={ (el) => this._flatList = el }
          onLayout={ ({nativeEvent}) => {
            const {width, height} = nativeEvent.layout;
            this.setState({
              width, height
            });
          } }
          onScroll={ ({ nativeEvent }) => {
            const { x } = nativeEvent.contentOffset;
            if(x === (this.props.data.length * this.state.width)) {
              this._flatList.scrollToOffset({x: 0, animated: false});
            }
          } }
          data={ this.getWrappableData(this.props.data) }
          pagingEnabled={true}
        />
      )
    
    };
    
    InfiniteFlatList.defaultProps = { };
    InfiniteFlatList.propTypes = { };
    

    This assumes you want to scroll horizontally.

    It probably isn't perfect; there is likely a better technique out there which uses FlatList's onEndReached callback, however this only seemed to fire once througohout. By polling the scroll offset of the FlatList, we can fire off our own equivalent as many times as needed. If you specify a getItemLayout prop, you'll be able to use scrollToIndex({index, animated?}) instead.

    Aug. 5, 2019 update

    On React native 0.60, one should use scrollToOffset as:

     this._flatList.scrollToOffset({offset: 0, animated: false});
    
    0 讨论(0)
  • 2020-12-04 02:29

    This works for me:

         <FlatList
              data={this.state.storesList}
              renderItem={({ item, index }) => renderItem(item, index)}
              keyExtractor={(item, index) => item.id.toString()}
              onEndReached={this.fetchMore}
              onEndReachedThreshold={0.1}
              ListFooterComponent={this.renderFooter}
              refreshing={this.state.refreshing}
            />
    
    
    renderFooter = () => {
        if (this.state.refreshing) {
          return <ActivityIndicator size="large" />;
        } else {
          return null;
        }
      };
    
    
      fetchMore = () => {
        if (this.state.refreshing){
          return null;
        }
        this.setState(
          (prevState) => {
            return { refreshing: true, pageNum: prevState.pageNum + 1 };
          },
          () => {
            this.sendAPIRequest(null , true);
          }
        );
      };
    

    The reason I used the following in the fetchMore function:

    if (this.state.refreshing){
          return null;
        }
    

    Is because when you setState to the pageNum it calls the render() function and then the fetchMore called again. This is written to prevent it. In addition, I set:

    refreshing: false
    

    after the sendAPIRequest is done. Pay attention about onEndReachedThreshold in FlatList:

    How far from the end (in units of visible length of the list) the bottom edge of the list must be from the end of the content to trigger the onEndReached callback.

    Meaning in my example (0.1) means: when you reach 10% of items from the bottom, the fetchMore callback is called. In my example, I have 10 items in the list, so when the last item is visible, fetchMore is called.

    0 讨论(0)
  • 2020-12-04 02:32

    I am not sure if you were able to resolve this but I was having the same problem and I am adding what worked well for me.

    onEndReachedThreshold=>onEndThreshold

    <FlatList
          data={this.state.data}
          renderItem={({ item }) => (
            <ListItem
              roundAvatar
              title={
                <Text style={{textAlign: 'left'}}> {item.name.first} {item.name.last}</Text>
              }
              subtitle={
                  <Text style={{textAlign: 'left'}}>{item.email}</Text>
              }
              avatar={{ uri: item.picture.thumbnail }}
              containerStyle={{ borderBottomWidth: 0 }}
            />
          )}
          ItemSeparatorComponent={this.renderSeparator}
          ListHeaderComponent={this.renderHeader}
          ListFooterComponent={this.renderFooter}
          keyExtractor={item => item.email}
          refreshing={this.state.refreshing}
          onRefresh={this.handleRefresh}
          onEndReached={this.handleLoadMore}
          onEndThreshold={0}
    
        />
    

    I hope this helps someone.

    0 讨论(0)
提交回复
热议问题