无法立即更新状态?

时间:2019-12-16 11:32:30

标签: javascript reactjs react-native firebase-realtime-database

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

所以在第一个功能中,我根据第二个功能状态更新了状态 而且效果很好

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

,但无法立即看到更新。

那我该如何处理呢?

警告

  

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

结构数组

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()内部的订单

尽管

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

编辑〜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"
        />

2 个答案:

答案 0 :(得分:1)

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

  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 });
  }

答案 1 :(得分:0)

您可以使用标志isMounted来检查何时使用setState。关于问题状态不是立即更新,可以使用ref.current查看更改后立即更新。

相关问题