Как эффективно вызвать setState в обоих случаях - успех и ошибка? - PullRequest
0 голосов
/ 04 сентября 2018

Я использую react, и у меня есть асинхронное действие, которое получает некоторые данные от API, используя axios. У меня также есть флаг (переменная состояния tableLoaded), которая описывает, выбираются ли данные.

    this.props.fetchDataAction(requestParams).then(
      () => {
        this.setState({
          data: this.props.reports.data
        });
      }
    ).then(() => {
      this.setState({ tableLoaded: true })
    });

Я хочу, чтобы мой флаг tableLoaded был установлен в true в обоих случаях - либо после успешного и неудачного вызова API, поэтому я просто добавил еще один then() в свой Promise, что вызывает функцию, устанавливающую этот флаг в true.

Мой вопрос - это лучшее решение для достижения моей цели? Или я должен повторить этот код в обоих случаях?

Ответы [ 3 ]

0 голосов
/ 04 сентября 2018

Вы должны использовать синтаксис Promise.finally .

this.props.fetchDataAction(requestParams)
.then(() => {
    // Do your thing on success
    this.setState({
        data: this.props.reports.data
    });
})
.catch((error) => {
    // Do something if failed
})
.finally(() => {
    // Do this in all cases..
    this.setState({ tableLoaded: true })
});

Edit: Если возврат от fetchDataAction является обещанием Axios, то вы должны заменить .finally на .then, поскольку Axios не предлагает метод finally. Я бы тогда сказал, что ваше первоначальное предложение было правильным. Вы можете прокомментировать второй .then, чтобы вы знали, почему.

this.props.fetchDataAction(requestParams)
.then(() => {
    // Do your thing on success
    this.setState({
        data: this.props.reports.data
    });
})
.catch((error) => {
    // Do something if failed
})
.then(() => { // Triggered in all cases by axios
    // Do this in all cases..
    this.setState({ tableLoaded: true })
});
0 голосов
/ 04 сентября 2018

Одна проблема, с которой вы столкнетесь при текущем подходе, состоит в том, что любые возможные ошибки будут препятствовать запуску последнего .then, позволяя tableLoaded оставаться false, если что-то делает пойти не так См. Это перо для примера этой проблемы.

Promise.finally - это один хороший способ обойти это, как указывает другой ответ, но я бы предпочел использовать async / await .

try {
  await this.props.fetchDataAction(requestParams)
  this.setState({
    data: this.props.reports.data
  })
} catch (error) {
  // handle error
}
this.setState({ tableLoaded: true })
0 голосов
/ 04 сентября 2018

Вы можете использовать all(), чтобы поймать успехи и неудачи

...