【问题标题】:React Native Flatlist Remove Item Removing Last ItemReact Native Flatlist 删除项目 删除最后一个项目
【发布时间】:2019-07-22 04:20:32
【问题描述】:

我正在使用“react-native-swipe-list-view”来尝试删除项目。出于某种原因,当我尝试删除一个项目时,它正在从平面列表中删除最后一个项目,即使该项目仍显示在数组中并且正确的项目已被删除。

当我删除一个项目时,基本上总是从平面列表中删除最后一个项目,即使该项目仍然存在于数据数组中。很奇怪的活动。当我离开并返回页面时,会显示正确的数据。

CoinList.js

import React, { Component } from "react";
import { FlatList, StyleSheet, Text, View , AsyncStorage } from "react-native";
import CoinListRow from './CoinListRow';


class CoinList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      coinList: null
    };
  }


  updateCoinList = (updatedCoins) => {
    this.setState(
      {coinList: updatedCoins}
    )
  }

  componentDidMount() {
    AsyncStorage.getItem("coins").then(value => {
      // need to convert returned object into an array
      this.setState({coinList: Object.values(JSON.parse(value))})
    });
  }

  render() {
    return (
      <View style={styles.container}>
        {this.state.coinList !== null ? <FlatList
          data={this.state.coinList}
          keyExtractor={(item, index) => index.toString()}
          extraData={this.state}
          renderItem={({item}) => <CoinListRow style={styles.item} item={item} updateCoinList={this.updateCoinList}/>}
        /> : null}
      </View>
    );
  }
}

export default CoinList;

CoinListRow:

import React, { Component } from "react";
import { withNavigation } from "react-navigation";
import { AsyncStorage } from "react-native";
import { View, StyleSheet, Text, TouchableOpacity } from "react-native";
import { ListItem } from "react-native-elements";
import { SwipeRow } from "react-native-swipe-list-view";

import images from "../../assets/logos/coinLogos";

class CoinListRow extends Component {
  constructor() {
    super();
    this.state = {
      coinInfo: null,
      disableInterstitialBtn: false
    };
  }

  componentDidMount() {
    const { item } = this.props;
    return fetch(`https://api.coincap.io/v2/assets/${item.card.slug}`)
      .then(response => response.json())
      .then(responseJson => {
        console.log(responseJson);
        this.setState({
          isLoading: false,
          coinInfo: responseJson.data
        });
      })
      .catch(error => {
        console.error(error);
      });
  }


  removeCoin = () => {
  AsyncStorage.getItem('coins')
    .then((coins) => {
      AsyncStorage.removeItem('coins');
      let c = coins ? JSON.parse(coins) : {};
      delete c[this.props.item.card.slug]
      AsyncStorage.setItem('coins', JSON.stringify(c));
      this.props.updateCoinList(Object.values(c));
    })
    .catch((error)=> {
      console.log(error);
      alert(error);
    }
    )
  }

  render() {
    const { coinInfo } = this.state;
    const { item } = this.props;
    console.log(this.state.coinInfo);
    return (
      <View>
        {this.state.coinInfo ? (
          <SwipeRow disableRightSwipe={true} rightOpenValue={-120}>
            <View style={styles.standaloneRowBack}>
              <Text style={styles.backTextWhite}></Text>
              <TouchableOpacity onPress={this.removeCoin}><Text style={styles.backTextWhite}>Remove Item</Text></TouchableOpacity>
            </View>
            <View>
              <ListItem
                key={item.card.slug}
                leftAvatar={{ source: images[item.card.slug] }}
                title={coinInfo.name}
                titleStyle={{ fontWeight: "bold" }}
                subtitle={coinInfo.symbol}
                onPress={this._openInterstitial}
                chevron
                bottomDivider={true}
              />
            </View>
          </SwipeRow>
        ) : null}
      </View>
    );
  }
}

export default withNavigation(CoinListRow);

【问题讨论】:

    标签: react-native asynchronous react-native-flatlist asyncstorage


    【解决方案1】:

    我认为它可能来自这个:

    removeCoin = () => {
      AsyncStorage.getItem('coins')
        .then((coins) => {
          AsyncStorage.removeItem('coins');
          let c = coins ? JSON.parse(coins) : {};
          delete c[this.props.item.card.slug]
          AsyncStorage.setItem('coins', JSON.stringify(c));
          this.props.updateCoinList(Object.values(c));
        })
        .catch((error)=> {
          console.log(error);
          alert(error);
        }
        )
      }
    

    您使用了一个异步函数,但在更新您的硬币之前您并没有真正等待它完成。不太确定,但您可以通过这种方式尝试(也许您需要对其进行编辑):

    removeCoin = () => {
      AsyncStorage.getItem('coins')
        .then((coins) => {
          AsyncStorage.removeItem('coins');
          let c = coins ? JSON.parse(coins) : {};
          delete c[this.props.item.card.slug]
          this.setState({coinItem: c});
        }).then(async() => {
          await AsyncStorage.setItem('coins', JSON.stringify(this.state.coinItem));
        }).then(() => {
          this.props.updateCoinList(Object.values(this.state.coinItem));
        })
        .catch((error)=> {
          console.log(error);
          alert(error);
        }
        )
      }
    

    【讨论】:

    • 不幸的是,它实际上正在更新,我可以看到状态是正确的,但它正在删除最后一行而不是正确的行。当我导航出去并返回时,它会记录正确的状态/因此被移除的硬币实际上不再在列表中,最后一行现在用正确的硬币重新出现。
    • 也许你可以在零食上重现它?会更容易提供帮助。
    【解决方案2】:

    我忘记根据不断变化的道具运行 componentDidUpdate。我打算做点心,然后意识到我在执行 git stash 时忘记保存代码:

    我在想如果我更新了父组件中的 props,它会通过传递新的 props 自动触发刷新,但由于组件已经挂载,我需要事后进行刷新。

     componentDidUpdate(prevProps) {
        const { item } = this.props;
        if (prevProps.item !== this.props.item) {
          return fetch(`https://api.coincap.io/v2/assets/${item.card.slug}`)
          .then(response => response.json())
          .then(responseJson => {
            this.setState({
              coinInfo: responseJson.data
            });
          })
          .catch(error => {
            console.error(error);
          });
        }
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多