无法立即更新状态? [英] Can't update state immediately?

查看:48
本文介绍了无法立即更新状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个双重功能,第一个我得到所有订单,第二个我得到所有拒绝的订单

I have an two function in the first one I get all orders, the second one I get all rejected orders

所以在第一个函数中,我根据第二个函数的状态来更新状态 而且效果很好

So in the first function, I update the state based on second function state and it's work well

但是当我从Firebase控制台删除项目时,虽然我使用on("value",()=>{})

but when I deleted an item from my Firebase console I can't see the updates immediately although I use on("value",()=>{})

那我该如何处理呢?

警告

无法在已卸载的组件上执行React状态更新.这是 没有操作,但这表明您的应用程序内存泄漏.

can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application.

结构数组

let ordersArray = [
   {"snapshotKey":"-awdawadsdwwd","username":"Joe"},
   {"snapshotKey":"-badsdasdad","username":"Annna"},
   {"snapshotKey":"-dasQwaddas","username":"lee"}
]

let rejectedOrders = ["-awdawadsdwwd","-dasQwaddas"] 

状态

this.state = {
      orders: [],
      rejectedOrders: [],
    };


componentDidMount() {
    try {
      this.getRejectedOrders();
      this.fetchOrders();
    } catch (err) {
      console.log('error', err);
    }
}

第一个功能

//Get all orders from DB

 fetchOrders = async () => {
    const {serviceName} = this.state;
    let uid = auth().currentUser.uid;
    const serviceStorage = await AsyncStorage.getItem('service');
    this.setState({serviceStorage});
    database()
      .ref(`Providers/CategoriesOrders/${serviceName || serviceStorage}`)
      .on('value', snapshot => {
        let orderArr = [];
        snapshot.forEach(childSnapshot => {
          orderArr.push({
            snapshotKey: childSnapshot.key,
            username: childSnapshot.val().username,
          });
        });
        this.setState(prevState => ({
          orders: orderArr.filter(
            order =>
              !prevState.rejectedOrders.some(key => order.snapshotKey === key),
          ),
          loading: false,
        }));
      });
  };

第二功能

// get an array of rejected orders

  getRejectedOrders = () => {
    let uid = auth().currentUser.uid;
    const ref = database().ref(`Providers/users/${uid}`);
    ref.on('value', snapshot => {
      let rejectedOrders = snapshot.val().rejectedOrders;
      this.setState({rejectedOrders});
    });
  };

JSX

render(){
   return (
        <OrdersList
          data={this.state.orders}
          extraData={this.state}
          screenName="OrderHomeDetails"
        />
      );
}

组件

const OrdersList = props => {
  return (
    <View style={styles.container}>
      <FlatList
        showsVerticalScrollIndicator={false}
        data={props.data}
        extraData={props.extraData}
        ListEmptyComponent={<EmptyList />}
        keyExtractor={(item, index) => index.toString()}
        legacyImplementation={true}
        contentContainerStyle={{
          flexGrow: 1.2,
        }}
        renderItem={({item}) => {
          return (
            <TouchableOpacity
              onPress={() =>
                props.navigation.navigate(props.screenName, {
                  username: item.username,
                  snapshotKey: item.snapshotKey,
                })
              }
             >

                <View>
                  <Icon name="person" color="#AEACAC" size={20} />
                  <Text> {item.username}</Text>
                </View>

            </TouchableOpacity>
          );
        }}
      />
    </View>
  );
};

export default withNavigation(OrdersList);

我认为OrdersList组件存在问题,因为当我在每个函数"fetchOrders()/getRejectedOrders()"中的setState之后的回调中记录状态时,我得到的新拒绝订单不是fetchOrders()内部的订单

I think the issue with OrdersList component because when I log state in a call back after setState inside every function"fetchOrders() /getRejectedOrders()" I got the new rejected orders just not orders inside fetchOrders()

尽管

though

当我向拒绝的订单数组添加/删除数据时,意味着getRejectedOrders()会发生变化,但fetchOrders()并不是因为它与这些东西无关',它会在第一次获取所有订单,然后根据某些内容对它们进行过滤订单没有更改,所以为什么要更新!"

" When I add/delete data to rejected order array that's mean getRejectedOrders() just will change but fetchOrders() not because it's not related with these things 'it's got all orders at first time then filter it based on something and these orders did not change so why will update! "

编辑〜1

fetchOrders = async () => {
    const {rejectedOrders, serviceName} = this.state;
    let uid = auth().currentUser.uid;
    const serviceStorage = await AsyncStorage.getItem('service');
    this.setState({serviceStorage});
    // await this.getRejectedOrders();
    database()
      .ref(`Providers/CategoriesOrders/${serviceName || serviceStorage}`)
      .on('value', snapshot => {
        let orderArr = [];
        snapshot.forEach(childSnapshot => {
          orderArr.push({
            snapshotKey: childSnapshot.key,
            username: childSnapshot.val().username,
          });
        });
        this.setState(
          prevState => ({
            orders: orderArr.filter(
              order =>
                !prevState.rejectedOrders.some(
                  key => order.snapshotKey === key,
                ),
            ),
            loading: false,
          }),
          () => console.log(this.state.orders), // I don't git anything if i add or delete rejected orders
        );
        console.log(orderArr); // I don't git anything if i add or delete rejected orders
      });
  };



 getRejectedOrders = async () => {
    let uid = auth().currentUser.uid;
    database()
      .ref(`Providers/users/${uid}`)
      .on('value', snapshot => {
        let rejectedOrders = snapshot.val().rejectedOrders;
        this.setState({rejectedOrders}, () =>
          console.log(this.state.rejectedOrders), // here's i got every single time i add or delete item i can see it in console log
        );
      });
  };




 <OrdersList
          data={this.state.orders}
          extraData={this.state.orders.length} // i add it but it's not effected 
          screenName="OrderHomeDetails"
        />

推荐答案

只要rejectedOrders得到更新,就应该更新orders.此外,请记住unsubcribe侦听器,以避免内存泄漏

You should update orders whenever rejectedOrders get updated. Besides, remember to unsubcribe listeners to avoid memory leak

  constructor(props) {
    super(props);
    this.allOrders = [];
    this.rejectedOrders = [];
    this.state = {
      orders: [],
    }
  }

  componentWillUnmount() {
    database()
      .ref(`Providers/CategoriesOrders/${serviceName || serviceStorage}`)
      .off('value', this.ordersCallback);
    database()
      .ref(`Providers/users/${uid}`)
      .off('value', this.rejectedOrderCallback);
  }

  fetchOrders = async () => {
    ...
    database()
      .ref(`Providers/CategoriesOrders/${serviceName || serviceStorage}`)
      .on('value', this.ordersCallback);
  };

  getRejectedOrders = async () => {
    let uid = auth().currentUser.uid;
    database()
      .ref(`Providers/users/${uid}`)
      .on('value', this.rejectedOrderCallback);
  };

  ordersCallback = (snapshot) => {
    let orderArr = [];
    snapshot.forEach(childSnapshot => {
      orderArr.push({
        snapshotKey: childSnapshot.key,
        username: childSnapshot.val().username,
      });
    });
    this.allOrders = orderArr;
    this.updateData()
  }

  rejectedOrderCallback = (snapshot) => {
    this.rejectedOrders = snapshot.val().rejectedOrders;
    this.updateData();
  }

  updateData() {
    const orders = this.allOrders.filter(order => this.rejectedOrders.some(key => order.snapshotKey === key));
    this.setState({ orders });
  }

这篇关于无法立即更新状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆