[英]React Native Flatlist gets endless loop onEndReached using redux
[英]Flatlist onEndReached endless loop
我正在使用state
来存储以下数据。
state = {
refresh: true,
isFetching: true,
showLoadingBottom: false,
data: []
};
在componentDidMount
我手动调用了一个函数_fetchData
,它将数据加载到this.state.data
。
当 flatlist 滚动到最后时,它会触发_fetchData
两次,最终两次返回相同的数据(这是另一个问题,为什么它会触发两次?)。
一旦 flatlist 到达末尾,即没有更多的数据从服务器返回,它就会进入一个无限循环,因为onEndReached
不断地一遍onEndReached
触发,即使没有从服务器返回新的数据并且this.state.data
仍然是相同的。
这是我的render
代码
render() {
return (
<View
style={{
flex: 1
}}>
<FlatList
refreshControl={
<RefreshControl
refreshing={this.state.refresh}
onRefresh={() => {
this.setState({
refresh: true
}, this._fetchData);
}}
title={"Pull To Refresh"}
tintColor={darkGrey}
titleColor={darkGrey}/>
}
onEndReachedThreshold={0.5}
onEndReached={() => {
this.setState({
showLoadingBottom: true
}, () => {
this._fetchData();
});
}}
showsVerticalScrollIndicator={false}
data={this.state.data}
ListFooterComponent={() => {
return (
this.state.showLoadingBottom &&
<View style={{padding: 10}}>
<ActivityIndicator size="small" color={colorAccent}/>
</View>
);
}}
renderItem={this._renderItem}
keyExtractor={(item) => item.id.toString()}
removeClippedSubviews={true}
/>
</View>
);
}
这是我的解决方案,可以更改以适应其他人的需求:基本上重要的部分是onEndReached={this.state.moreData && this.retrieveMore}
。 所以你可以在你的onEndReached
函数中测试天气是否有数据(在我的情况下,如果我们只返回 1 个对象,我知道它已经完成)然后将 state this.state.moreData
设置为 false。
<SafeAreaView style={styles.container}>
<FlatList
data={Object.values(this.state.documentData)}
// Render Items
renderItem={({ item }) => (
<ItemSelector
item={item}
onPress={() => {this.selectItem(item)}}
/>
)}
// On End Reached (Takes in a function)
onEndReached={this.state.moreData && this.retrieveMore}
// How Close To The End Of List Until Next Data Request Is Made
onEndReachedThreshold={1}
ListEmptyComponent={
<Text>No jobs to show</Text>
}
/>
</SafeAreaView>
retrieveMore = async () => {
try {
// Set State: Refreshing
this._isMounted && this.setState({ refreshing: true });
fbDb.ref('job')
.orderByKey()
.startAt(this.state.lastVisible) //Start at the last item we found
.limitToFirst(this.state.limit) //Limit queries returned per page
.once('value', snapshot => {
//check if we got a result
if(snapshot.numChildren() > 1){
.....
this._isMounted && this.setState({
documentData: newstate,
lastVisible: lastVisible,
refreshing: false, //Hide loading icon
});
} else {
this._isMounted && this.setState({
refreshing: false, //Hide loading icon
moreData: false
});
}
});
}
catch (error) {
console.log(error);
}
};
您正在使用加载数据时正在呈现的组件,对吗? 所以你的平面列表需要重新渲染。 您必须确保即使多次到达终点,也只调用一次 fetch 方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.