【问题标题】:onEndReached causing multiple items displaying on the listviewonEndReached 导致列表视图上显示多个项目
【发布时间】:2018-04-20 07:41:06
【问题描述】:

我最终在我的列表视图上重复了多个项目,因为由于某种原因多次使用相同的参数 'page=1' 调用 api,而且 onEndReached 在我不滚动的情况下自行触发。

我尝试过这样的事情:

 componentDidMount() {
        this.fetchCategories();
 }


fetchCategories() {
   this.setState({isLoading: true});
   categoryApi.getOne(this.state.page).then(response => {
       if (response.data) {
           this.setState({
               categories: this.state.categories.concat(response.data.data),
               isLoading: false,
           });
       } else {
           this.setState({isLoading: false});
           Alert.alert(
               'Something wrong happened!',
               'My Alert Msg',
               [],
               {cancelable: true}
           )
       }
   }); }

this.state = {
     isLoading: false,
     categories: [],
     page: 1,
};

showMore = () => {
    this.setState({page: this.state.page + 1});
    this.fetchCategories();
}; 



<FlatList
  data={this.state.categories}
  extraData={this.state}
  renderItem={(rowData) => <CategoryItem navigate={navigate} item={rowData}/>}
  onEndReached={this.showMore}
  keyExtractor={(item, index) => index}
 />

我尝试了什么: 将 showMore 更改为:

showMore = () => {
        // console.log("End reached.");
        this.setState(prevState =>({
            page: prevState + 1
        }), () => {
            this.fetchCategories();
        });
}; 

我仍然可以看到 page=1 的重复项,api 仍然被多次调用参数 page = 1!

有人知道我怎样才能避免这种事情吗?

【问题讨论】:

  • 你试过onEndReachedThreshold={0.5} 吗?
  • @PritishVaidya 看起来 onEndReachedThreshold={0.5} 解决了自行触发的问题,但是当我尝试滚动时,我仍然可以在列表中看到重复的项目,似乎我的 api 在页面状态之前被调用变了,所以基本上页面值没有及时递增!
  • 您正在尝试在this.state.categories.concat(response.data.data) 此处合并数据,因此它将其添加到数组中,而不是您应该合并数组。
  • 所以你说我应该使用 .merge() 而不是 .concat() ?

标签: javascript reactjs react-native ecmascript-6 react-native-android


【解决方案1】:

您必须将onEndReachedThreshold 与onEndReached 结合使用,以防止发生奇怪的行为

如docs中所述

onEndReached :当滚动位置在渲染内容的onEndReachedThreshold 内时调用一次。

因此您可以将值设置为onEndReachedThreshold={0.5}

0.5 将在内容结尾在列表可见长度的一半以内时触发onEndReached

为了对项目进行重复数据删除,您需要将它们合并为 concat 组合两个具有或不具有唯一值的数组。

因此,像往常一样,您可以使用es6 spread operator

例子

let arr1 = [1, 2, 3];
let arr2 = [3, 5, 6];

let deDupeIt = (...arrs) => [ ...new Set( [].concat(...arrs) ) ];

let dedupedArrays = deDupeIt(arr1, arr2)
console.log(dedupedArrays)

在您的情况下,在某处定义函数并将其称为

this.setState({
               categories: deDupeIt(this.state.categories, response.data.data),
               isLoading: false,
           });

注意:

如果您使用的是代码的第二部分 sn-p 应该使用prevState.page + 1 而不是prevState + 1

【讨论】:

  • 你说的是不是类别:this.state.categories.concat(response.data.data),我应该让 deDupeIt = (...arrs) => [ ...new设置( [].concat(...arrs) ) ];让 dedupedArrays = deDupeIt(this.state.categories, response.data.data) this.state.categories.concat(dedupedArrays) ?
  • 已更新,无论您身在何处都可以这样尝试concating
  • 我按照你的建议做了同样的事情,我仍然可以看到重复的项目。
  • 你可以为项目添加response objects,包含一些duplicates,我认为这可能是项目中嵌套重复对象的问题。
  • 我认为问题根本不在于 concat,问题是我的 api 调用使用相同的参数 page:1 调用了两次
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多