невозможно установить внутри оператора if - PullRequest
3 голосов
/ 23 марта 2019

Попытка обновить состояние реакции в операторе if.

Когда снимок возвращает истину -> переключить состояние с истинного на ложное.Когда снимок возвращает ложь -> переключить состояние с ложного на истинное.

Если я console.log (this.state.notification) выше оператора if, все нормально, когда я регистрируюсь или хочу редактировать внутри ifУтверждение, что я получаю сообщение об ошибке: [Необработанное отклонение обещания: Ошибка типа: undefined не является объектом (оценка '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 Ответ

5 голосов
/ 23 марта 2019

Здесь есть три вопроса (возможно, четыре):: -)

  1. this - это не то, что вы ожидаете в обратном вызове then. Вы решите это, используя ответы из этого вопроса , , но см. # 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 для его обновления. Помните, что обновления состояния асинхронны , ваше состояние еще не изменится с момента этого 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')
});
...