This.setState возвращает обещание в реакции - PullRequest
0 голосов
/ 21 ноября 2018

Я сделал свой componentWillMount() асинхронный.Теперь я могу использовать await с setState.

Вот пример кода:

componentWillMount = async() => {
  const { location, fetchRooms } = this.props
  await this.setState({ roomId: room && room.roomId ? room.roomId : 0 })
  fetchRooms()
}

Итак, вопрос в том, this.setState возвращает обещание, потому что я могу использовать awaitс ним?

Редактировать

Когда я ставлю await, он запускается в последовательности 1, 2, 3 А когда я удаляю await, тогда он запускается 1, 3, 2 ??

  componentWillMount = async() => {
    const { location, fetchRooms } = this.props
    console.log(1)
    await this.setState({ roomId: room && room.roomId ? room.roomId : 0 } => {
      console.log(2)
    })
    console.log(3)
    fetchRooms()
  }

Ответы [ 5 ]

0 голосов
/ 16 июля 2019

Вы можете просто настроить Обещание для setState

  componentWillMount = async () => {
    console.log(1);
    await this.setRooms();
    console.log(3);
  };

  setRooms = () => {
    const { fetchRooms } = this.props;
    return fetchRooms().then(({ room }) => {
      this.setState({ roomId: room && room.roomId ? room.roomId : 0 }, _ =>
        console.log(2)
      );
    });
  };

или

  setRooms = async () => {
    const { fetchRooms } = this.props;
    const { room } = await fetchRooms();

    return new Promise(resolve => {
      this.setState({ roomId: room && room.roomId ? room.roomId : 0 }, _ =>
        resolve()
      );
    });
  };

Надеюсь, эта помощь = D

0 голосов
/ 10 января 2019

Вы можете обещать this.setState, чтобы вы могли использовать React API в качестве обещания.Вот как я заставил это работать:

class LyricsGrid extends Component {
  constructor(props) {
    super(props);
    this.setAsyncState = this.setAsyncState.bind(this);
  }

  setAsyncState = (newState) =>
    new Promise((resolve) => this.setState(newState, () => resolve()));

Позже я звоню this.setAsyncState, используя стандартный API Promise:

this.setAsyncState({ lyricsCorpus, matrix, count })
  .then(foo1)
  .then(foo2)
  .catch(err => console.error(err))
0 голосов
/ 21 ноября 2018

Он не возвращает обещание.

Вы можете поставить ключевое слово await перед любым выражением.Он не действует, если это выражение не соответствует обещанию.

setState принимает обратный вызов.

0 голосов
/ 21 ноября 2018

setState обычно не используется с обещаниями, потому что такая необходимость встречается редко.Если метод, вызываемый после обновления состояния (fetchRooms), полагается на обновленное состояние (roomId), он может получить к нему доступ другим способом, например, в качестве параметра.

setState использует обратные вызовы и не используетне верни обещание.Поскольку это требуется редко, создание неиспользуемого обещания может привести к дополнительным расходам.

Чтобы вернуть обещание, можно обещать setState, как это предлагается в в этом ответе .

Прикрепленный код работает с await, потому что это хак.await ... является синтаксическим сахаром для Promise.resolve(...).then(...).await производит задержку в один тик, что позволяет оценивать следующую строку после завершения обновления состояния, что позволяет оценивать код в заданном порядке.Это то же самое, что:

this.setState({ roomId: room && room.roomId ? room.roomId : 0 } => {
  console.log(2)
})

setTimeout(() => {
  console.log(3)
});

Нет гарантии, что заказ останется таким же при других условиях.Кроме того, первый setState обратный вызов не является подходящим местом для проверки, было ли обновлено состояние, для этого и нужен второй обратный вызов.

0 голосов
/ 21 ноября 2018

setState не возвращает обещание.

setState имеет обратный вызов.

this.setState({
    ...this.state,
    key: value,
}, () => {
    //finished
});
...