web-dev-qa-db-ja.com

非同期setStateを使用する

アクションをディスパッチする機能があります。アクションの前後にローダーを表示したいと思います。 setStateに渡されるオブジェクトを構成する反応を知っています。問題は、非同期の方法でプロパティを更新する方法です:

handleChange(input) {
    this.setState({ load: true })
    this.props.actions.getItemsFromThirtParty(input)
    this.setState({ load: false })
}

基本的に、このプロパティをアプリケーション状態の一部として(Reduxを使用して)配置すれば、すべてうまくいきましたが、このプロパティをコンポーネント状態のみにすることを本当に好みます。

20
Chen

最初のsetStateのコールバックで残りのコードをラップします。

_handleChange(input) {
  this.setState({
    load: true
  }, () => {
    this.props.actions.getItemsFromThirtParty(input)
    this.setState({ load: false })
  })
}
_

これにより、loadが呼び出される前にtruegetItemsFromThirtPartyに設定され、loadfalseに戻されます。

これは、getItemsFromThirtParty関数が同期的であることを前提としています。そうでない場合は、promiseに変換してから、連鎖then()メソッド内で最後のsetStateを呼び出します。

_handleChange(input) {
  this.setState({
    load: true
  }, () => {
    this.props.actions.getItemsFromThirtParty(input)
      .then(() => {
        this.setState({ load: false })
      })
  })
}
_
24
James Donnelly

promiseでsetStateをラップし、以下のようにasync/awaitを使用できます。

setStateAsync(state) {
    return new Promise((resolve) => {
      this.setState(state, resolve)
    });
}

async handleChange(input) {
    await this.setStateAsync({ load: true });
    this.props.actions.getItemsFromThirtParty(input);
    await this.setStateAsync({ load: false })
}

ソース: REACTを使用したASYNC AWAIT

51
Tejas Rao

できることは次のとおりです...

  1. アクションを変更して、onFetchCompleteとともにinputコールバックを受け取ります。
  2. ハンドルを変更-に変更

    handleChange(input) {
        this.setState({ load: true }, ()=>
            this.props.actions.getItemsFromThirtParty(input,
            ()=>this.setState({ load: false }))
        );
    }
    

これにより、約束ベースの方法で記述されていない場合でも、アクションプロセッサコードが状態変更コールバックを呼び出すことができます。

1
hazardous

「async-await」setStateのTypeScript実装を次に示します。

async function setStateAsync<P, S, K extends keyof S>(
  component: Component<P, S>,
  state:
    ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) |
    Pick<S, K> |
    S |
    null
) {
  return new Promise(resolve => component.setState(state, resolve));
}
1
Tobiq

アクションクリエーターとasync/awaitに対するpromiseを使用した小さな更新は素晴らしい動作をし、「then」チェーンと比較してコードをさらにきれいにします。

(async () => {
   try {
    await this.props.actions.async1(this.state.data1);
    await this.props.actions.async2(this.state.data2) 
    this.setState({ load: false );
   } catch (e) {
    this.setState({load: false, notify: "error"});
   }
})();

もちろん、それは好みの問題です。

編集:不足しているブラケットを追加

0
Chen