Настройка состояния реакции правильным образом

#reactjs

Вопрос:

Я узнал, что вы можете установить состояние двумя способами:

  1. Если это зависит от значения предыдущего состояния
  2. Если это не зависит от значения предыдущего состояния

Второй вариант довольно прост: просто используйте setState со свойствами, которые вы хотите:

 this.setState({
  name: "John"
});
 

Но если это первый вариант, вы должны использовать setState с обратным вызовом. Я создаю «игру» flipcoin, и вот как я разработал ее состояние:

 this.state = {
  count: 0,
  heads: 0,
  tails: 0,
  currFace: null,
};
 

И вот моя функция «FlipCoin» :

   flipCoin() {
    let face = choice(this.props.coin);

    this.setState((currState) => {
      let newState = {
        ...currState,
        currFace: face,
        count: currState.count   1,
      };
      if (face.includes("heads")) {
        newState.heads  = 1;
      } else {
        newState.tails  = 1;
      }
      return newState;
    });
  }
 

Насколько я знаю, когда вы используете setState с функцией обратного вызова, это похоже на то, что он ждет, пока react завершит обновление состояния, а затем вернет новое состояние. Это правильно или моя логика неверна?

Еще одна вещь: когда я проверил приложение с помощью React Dev Tools, когда оно изменило свое состояние, для его обновления потребовалось несколько секунд. Я не пытаюсь кусать щетку или что-то в этом роде, я просто подумал, что это будет «быстрее».

Заранее спасибо!

Комментарии:

1. Состояние настройки является асинхронным.

2. Все обновления состояния реакции являются асинхронными, функциональными или нет. reactjs.org/docs/… Теперь, хотя это говорит о том, что они могут быть асинхронными, это почти всегда имело место при обновлении состояния.

3. Поскольку react всегда обновляет состояние асинхронно, я думаю, вам нужно понять, как работает цикл асинхронности и событий в JS. youtube.com/watch?v=8aGhZQkoFbQ

4. Обновления состояния реакции, как правило, очень быстрые, поэтому я подозреваю, что это что-то в вашем коде, требующее «дополнительного времени». Что choice(this.props.coin); происходит?

Ответ №1:

Использование функций обратного вызова при настройке состояния связано с закрытием, а не с синхронностью. Рассмотрим следующие примеры:

 onClick={() => {
  this.setState({ count: this.state.count   1 });
  this.setState({ count: this.state.count   1 });
}}
 

по сравнению с этим:

 onClick={() => {
  this.setState(cur => ({ count: cur.count   1 }));
  this.setState(cur => ({ count: cur.count   1 }));
}}
 

Предполагая this.state.count 0 , что это начало, этот первый пример в конечном итоге будет иметь count значение 1, тогда как второй пример будет иметь count значение 2. Это связано с тем, что в первом случае обе функции настройки состояния имеют закрытие по this.state.count сравнению с тем, когда было его значение 0 . Во втором случае cur всегда будет текущее состояние, и поэтому один из установщиков состояния увеличит его до 1, а следующий-до 2.

Комментарии:

1. Я не думаю, что ОП спрашивает о разнице между ними, а скорее спрашивает, почему их конкретные обновления занимают пару секунд. Похоже, они понимают зависимость от предыдущего состояния.