1. ホーム
  2. reactjs

[解決済み] 非同期のcomponentDidMount()を使うのは良いことですか?

2022-03-12 17:45:25

質問

を使用していますか? componentDidMount() を非同期関数として使用することは、React Native では良い習慣ですか、それとも避けた方が良いですか?

から情報を取得する必要があります。 AsyncStorage コンポーネントがマウントされるとき、私が知っている唯一の方法は、コンポーネントがマウントされるときに componentDidMount() 関数を非同期で実行します。

async componentDidMount() {
    let auth = await this.getAuth();
    if (auth) 
        this.checkAuth(auth);
}

それについて何か問題があるのか、また他に解決策はあるのか。

どのように解決するのですか?

まずは、その違いを指摘し、どのようなトラブルが起こりうるかを判断することから始めましょう。

以下は、asyncと"sync"のコードです。 componentDidMount() ライフサイクルメソッド

// This is typescript code
componentDidMount(): void { /* do something */ }

async componentDidMount(): Promise<void> {
    /* do something */
    /* You can use "await" here */
}

コードを見ると、次のような違いが指摘できる。

  1. async のキーワードを使用します。タイプスクリプトでは、これは単なるコードマーカーに過ぎない。これは2つのことをする。
    • 戻り値の型を強制的に Promise<void> ではなく void . 戻り値の型を明示的にpromise以外(ex: void)に指定すると、typescriptはエラーを吐き出します。
    • を使用できるようにします。 await キーワードをメソッド内で使用します。
  2. 戻り値の型が void から Promise<void>
    • できるようになったということです。
      async someMethod(): Promise<void> { await componentDidMount(); }
  3. を使用できるようになりました。 await キーワードをメソッド内で使用し、一時的にその実行を停止します。このように

    async componentDidMount(): Promise<void> {
        const users = await axios.get<string>("http://localhost:9001/users");
        const questions = await axios.get<string>("http://localhost:9001/questions");
    
        // Sleep for 10 seconds
        await new Promise(resolve => { setTimeout(resolve, 10000); });
    
        // This line of code will be executed after 10+ seconds
        this.setState({users, questions});
        return Promise.resolve();
    }
    
    

さて、どうしてトラブルが起きるのでしょうか?

  1. async キーワードは全く無害です。
  2. を呼び出す必要があるような状況は想像もつきません。 componentDidMount() メソッドを使用するため、戻り値の型は Promise<void> も無害です。

    の戻り値の型を持つメソッドを呼び出すと Promise<void> がなく await のキーワードで呼び出したとしても、戻り値の型が void .

  3. の後のライフサイクルメソッドは存在しないので。 componentDidMount() の実行を遅らせることは、かなり安全だと思われます。しかし、困ったことがあります。

    例えば、上記の this.setState({users, questions}); は10秒後に実行されます。遅延時間の途中で、別の...

    this.setState({users: newerUsers, questions: newerQuestions});

    ... は正常に実行され、DOM が更新されました。その結果は、ユーザーにも見えるようになった。時計は動き続け、10秒が経過した。遅れていた this.setState(...) が実行され、DOMは再び更新され、今度は古いユーザーと古い質問で更新されます。結果はユーザーにも表示されます。

=>かなり安全(100%とは言い切れませんが)なのは asynccomponentDidMount() メソッドを使用します。私はこのメソッドの大ファンであり、今のところ頭を悩ませるような問題には遭遇していません。