首页 > 解决方案 > 如果我的 API 没有分页,如何添加加载更多功能 - 反应原生?

问题描述

在主屏幕中,我从 API 获取数据“歌曲”并将其保存在状态“大数组”中。我用FlatList它来渲染它,所以它渲染得很好,但我的滚动太长了!

所以在dataFlatList 道具中,我像这样对数组进行切片

<FlatList
   data={songs.slice(0,9)}
   ...
/>

它按预期呈现 10 首歌曲:D 但我想在滚动到结束时添加更多加载

我的想法是在状态中添加一个标志,例如

state={
   page: 10
}


<FlatList
      data={songs.slice(0,this.state.page)}
      onEndReached={this.handleLoadMore}
      onEndReachedThreshold={0}
       ...
/>


handleLoadMore = () => {
this.state.songs.length <= this.state.page ? this.setState({page: this.state.page + 10, loading: true}) : null
  };

那么有任何其他想法我该如何处理这种情况?

编辑

完整的 FlatList 代码片段

  // recent Songs FlatList
  _renderItem = ({item, index}) => {
    const {recent_songs} = this.state;
    return (
      <TouchableNativeFeed
        key={item.id}
        onPress={() => {
          this.props.saveSongs(recent_songs, index);
          this.props.isPlaying(true);
          this.props.isPauseTrigger(!this.props.isPauseTrigger);
        }}
        background={TouchableNativeFeedback.Ripple('white')}
        delayPressIn={0}
        useForeground>
        <Card style={styles.card} noShadow={true}>
          <FastImage
            source={{uri: item.img}}
            resizeMode={FastImage.resizeMode.cover}
            style={styles.cardImg}
          />
          <Body style={styles.cardItem}>
            <View style={styles.radioCardName}>
              <View style={styles.cardViewFlex}>
                <Text
                  lineBreakMode="tail"
                  ellipsizeMode="tail"
                  numberOfLines={1}
                  style={styles.text}>
                  {item.name}
                </Text>
              </View>
            </View>
          </Body>
        </Card>
      </TouchableNativeFeed>
    );
  };


{/* Recent Songs Here*/}
              <View style={{marginVertical: 10}}>
                <FlatList
                  style={{flex: 1}}
                  horizontal={true}
                  showsHorizontalScrollIndicator={false}
                  data={recent_songs.slice(0, 10)}
                  contentContainerStyle={{flexGrow: 1}}
                  ListEmptyComponent={<EmptyList />}
                  keyExtractor={(track, index) => track.id.toString()}
                  initialNumToRender={10}
                  renderItem={this._renderItem}
                />
              </View>

标签: javascriptreactjsreact-native

解决方案


像这样的平面列表和本地分页

  constructor(props) {
        super(props); 
        this.state = {
            ...
            itemPerPage : 10
            currentPage : 1, // we keep a track inside the state on each page we are for pagination
            songs:[], // contain the songs used by flatlist to render
            allSongs : [ ] // contain all the songs returned by api
        }
    }


   async componentDidMount() {
        // get the songs from api
        let allSongs = await GetSONGS(); 
        this.setState({ allSongs   , songs: allSongs.slice(0,this.state.currentPage*this.state.itemPerPage ) });
   }


   handleLoadMore = async() => {             
        this.setState({
            songs: [ ...this.state.songs ,  allSongs.slice(this.state.currentPage*this.state.itemPerPage,(this.state.currentPage+1)*this.state.itemPerPage )   ]   , // concat the old and new data together
            currentPage : this.state.currentPage +1
        })
    }


    render(){
     return(
      <FlatList               
            data={this.state.songs}
            keyExtractor={(item, index) => index.toString()}        
            initialNumToRender={10}   // how many item to display first
            onEndReachedThreshold={5} // so when you are at 5 pixel from the bottom react run onEndReached function
            onEndReached={() => {
                this.handleLoadMore();
            }}
        />
        )
    }

无论如何,我RecyclerListView在以前的项目中使用来呈现 10 000 个元素的列表


推荐阅读