【问题标题】:RefreshControll data duplicate everytime do pull to refresh on ScrollView in React nativeRefreshControl 数据重复每次在 React Native 中拉动以刷新 ScrollView
【发布时间】:2020-11-05 07:30:26
【问题描述】:

说明
我在 React Native 中使用 RequestController 实现了一个拉取请求,每次我拉动刷新相同的数据时,都会一遍又一遍地添加到平面列表中。我不是在平面列表中实现拉取请求,而是在包裹FlatListScrollView 上实现。

操作

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 新手,你能告诉我解决这个问题的简单方法吗?
  • 查看下面的答案...

标签: javascript react-native uirefreshcontrol


【解决方案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});
            });
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      相关资源
      最近更新 更多