RefreshControl 数据重复每次在 React Native 中拉动以刷新 ScrollView
Posted
技术标签:
【中文标题】RefreshControl 数据重复每次在 React Native 中拉动以刷新 ScrollView【英文标题】:RefreshControll data duplicate everytime do pull to refresh on ScrollView in React native 【发布时间】:2020-11-05 07:30:26 【问题描述】:说明
我在 React Native 中使用 RequestController
实现了一个拉取请求,每次我拉动刷新相同的数据时,都会一遍又一遍地添加到平面列表中。我不是在平面列表中实现拉取请求,而是在包裹FlatList
的ScrollView
上实现。
操作
import React, Component from 'react';
import View, StyleSheet, Text, Button, Modal, Dimensions, ScrollView, TextInput, TouchableOpacity, StatusBar, Image, Platform, TouchableNativeFeedback,FlatList, ImageBackground, RefreshControl from 'react-native';
import axios from 'axios';
class HomeScreen extends Component
state =
refreshing: false,
componentDidMount()
this.searchApi();
searchApi = async() =>
const response = await axios.get('http://73udkYid.ngrok.io/api/v1/products',
headers:
"x-auth-token":"eyJfaWQiOiI1ZdfjzZmM4YjIwYjBjZDQyMmJkNzUiLCJpYXQiOjE2MD"
);
this.setState(results: [...this.state.results, response.data]);
_onRefresh = () =>
this.setState(refreshing: true);
this.searchApi().then(() =>
this.setState(refreshing: false);
);
render()
let finalGames = [];
this.state.results.forEach(obj =>
Object.keys(obj).forEach(key =>
finalGames.push(obj[key]);
);
);
return (
<ScrollView style=flex: 1,backgroundColor: 'white',
refreshControl =
<RefreshControl
refreshing = this.state.refreshing
onRefresh=this._onRefresh
/>
>
<FlatList
data = finalGames
keyExtractor = (item, index) => index.toString()
renderItem = (item: itemData) =>
if(itemData.empty == true)
return <View style = [styles.item,styles.itemInvisible]/>
return (
<View style = flex: 1, margin: 4>
<View style = styles.item>
<TouchableOpacity
onPress = () =>
this.setState( viewController: this.state.viewController++ )
this.props.navigation.navigate(
"ProductDetail",
itemDataDetail: itemData,
businessname:this.props.navigation.state.params.businessname,
viewController: this.state.viewController,
)
>
<View>
<ImageBackground
source= uri: itemData.photo
style= width:'100%',aspectRatio: 1, borderRadius: 15, borderWidth:1, borderColor:"#FAFAFA", overflow: 'hidden'>
</ImageBackground>
<View style = margin: 5>
<Text style = color: '#2E2E2E', fontWeight:"bold" numberOfLines=1>itemData.item</Text>
<Text style = color: '#2E2E2E', fontSize: 12, fontWeight:"normal", alignSelf: 'flex-start' numberOfLines=1>Available now | Sold out</Text>
<Text style = color: 'white', fontSize: 18, fontWeight:"bold", backgroundColor:"#DE1F38", alignSelf: 'flex-start', paddingHorizontal: 10,paddingVertical:2,borderRadius: 8,overflow: 'hidden', marginTop: 5 numberOfLines=1>$itemData.price</Text>
</View>
</View>
</TouchableOpacity>
</View>
</View>
</ScrollView>
);
/>
输出 每次触发新的拉取刷新时都会复制数据
【问题讨论】:
这很有意义......因为您将新结果连接到当前结果列表中,状态为this.setState(results: [...this.state.results, response.data]);
如何解决这个@Hend El-Salhi
我是 React Native 新手,你能告诉我解决这个问题的简单方法吗?
查看下面的答案...
【参考方案1】:
我假设您的 api 调用会返回整个产品列表
此行将 api-response-data 连接到您在组件状态中已有的产品列表
this.setState(results: [...this.state.results, response.data]);
试试这个吧……
this.setState( results: response.data );
【讨论】:
我已经试过了,我将我的结果连接起来,因为它们是我的 api 调用返回的一个复杂的承诺,这就是我想将它们放在一个新数组中的原因。有什么方法可以将它们放在新数组中而不像以前那样连接? 你能 console.log 这个console.log(await response.data)
吗?
感谢您的帮助,您已经给了我有用的提示。我很感激。【参考方案2】:
您应该替换您的数据而不是连接。使用:
this.setState( results: response.data );
另外,您应该使用 FlatList 'onRefresh' 属性来实现刷新功能,而不是在父级上使用额外的 ScrollView。
【讨论】:
我知道这一点,但是问题是我从 api-call 返回的是包含 id 和属性的对象,所以我必须使用我的渲染函数下的一些步骤删除 id,所以我决定将它们放入新数组中。 感谢您的帮助,您已经给了我有用的提示。我很感激。 那么在这种情况下有一个更好的方法。您应该保持键值对原样并生成一个新的 id 数组并将其提供给 FlatList。然后在 renderItem 中,您将获得密钥作为项目,因此您可以使用该密钥从主对象简单地访问该对象,例如: renderItem(item) const gameItem = this.state.results[item] 这样您的数据将更易于管理且易于访问【参考方案3】:哦,我找到了办法。我只需要这样做。
this.setState(results: [response.data]);
【讨论】:
【参考方案4】:我遇到了和你一样的问题, 我刷新的时候,数据是(data)+[(data)+(new_data)]。
这里发生的是数据被添加到这个变量的数组中:结果。 为防止这种情况,您必须首先清除此变量:results。 所以您的代码将如下所示。
state =
refreshing: false,
results : [],
当 API 运行时,这个数组将填充 results[some_data,some_data,some_data,..]
,
刷新时-> 第一个:结果将为空, 第二:使用 API 中新添加的数据重新分配该数组。
_onRefresh = () =>
this.setState(results: []);
this.setState(refreshing: true);
this.searchApi().then(() =>
this.setState(refreshing: false);
);
【讨论】:
以上是关于RefreshControl 数据重复每次在 React Native 中拉动以刷新 ScrollView的主要内容,如果未能解决你的问题,请参考以下文章
ReactNative进阶(十七):RefreshControl组件实现刷新效果
ReactNative进阶(十七):RefreshControl组件实现刷新效果