无法在if语句中设置状态

时间:2019-03-23 13:44:29

标签: javascript firebase react-native setstate

尝试更新if语句中的反应状态。

当快照返回true时->将状态从true切换为false。 当快照返回false时->将状态从false切换为true。

如果我在if语句上方使用console.log(this.state.notification),则一切正常,当我登录或想在if语句中进行编辑时,我会不断出错: [未处理的承诺拒绝:TypeError:未定义不是对象(正在评估'this.state.notification')]]

我尝试使用绑定,但是没有用。

请帮助!

state = {
    darkMode: true,
    notification: true
};


toggleNotification = async () => {

    console.log(this.state.notification);       // no error

    const currentUserId = firebase.auth().currentUser.uid;
    const ref = firebase.database().ref("users/" + currentUserId + "/notification");

    ref.once("value").then(function(snapshot) {
      if(snapshot){
        this.setState({ notification: false })  // error
        console.log(this.state.notification);   // error
        console.log('First check')
      } else {
        this.setState({ notification: true })   // error
        console.log(this.state.notification);   // error
        console.log('Second check')
      }
    });
};

1 个答案:

答案 0 :(得分:5)

这里有三个问题(也许是四个)::-)

  1. this不是您在then回调中所期望的。您可以使用this question的答案来解决这个问题,请参阅#2:

  2. 不要在then函数的诺言中使用async;使用await

  3. “未处理的承诺拒绝”告诉我们,toggleNotification函数中没有错误在处理。请记住,async函数会返回诺言,诺言的基本规则之一是:处理错误,或将诺言链传播到将要实现的东西。

上面的#1被#2取代。这是在该函数中实现#2的方式:

toggleNotification = async () => {

    console.log(this.state.notification);

    const currentUserId = firebase.auth().currentUser.uid;
    const ref = firebase.database().ref("users/" + currentUserId + "/notification");

    const snapshot = await ref.once("value"); // <=====
    if(snapshot){
        this.setState({ notification: false });
        console.log(this.state.notification);
        console.log('First check')
    } else {
        this.setState({ notification: true });
        console.log(this.state.notification);
        console.log('Second check')
    }
};

(#3,您在呼叫 toggleNotification处进行。)


我注意到您在致电this.state.notification进行更新之后登录了setState。请记住,state updates are asynchronous,自该log调用起,您的状态尚未更改。如果要记录更新的状态,请使用完成回调(setState的第二个参数:

this.setState({notification: false}, () => {
    console.log(this.state);
});

(当然,如果您有意记录this.state.notification的旧值,这很公平,尽管如果您的意图是在setState调用之前进行此操作可能会更好,因为这很容易否则会误读。)


如果愿意,可以避免在if / else

中重复代码
const notification = !await ref.once("value");
// Notice -----------^
this.setState({notification}, () => {
    console.log(this.state.notification);
    console.log(notification ? 'Second check' : 'First check')
});