尝试更新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')
}
});
};
答案 0 :(得分:5)
这里有三个问题(也许是四个)::-)
this
不是您在then
回调中所期望的。您可以使用this question的答案来解决这个问题,但请参阅#2:
不要在then
函数的诺言中使用async
;使用await
。
“未处理的承诺拒绝”告诉我们,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')
});