Help us understand the problem. What is going on with this article?

React コンポーネント作成時に非同期通信したいときは componentDidMount に書こう

More than 1 year has passed since last update.

componentWillMount vs componentDidMount

「React コンポーネントを画面に表示する際に、サーバーからデータを非同期で取得して、その結果を表示に使う」というのはよくあることかと思いますが、その非同期通信処理はどこに書けばよいでしょうか?パッと浮かぶのは次のどちらかでしょう:

  • componentWillMount()
  • componentDidMount()

どちらに書くべきなのか調べてみました。

結論: componentDidMount の方がよい

表題の通りですが、componentDidMount() の方がよいみたいです。理由は下記。

プログラマーに誤解を与えない

componentWillMount() 内に setState() を書くと、なんとなく render() までに state が設定完了するように錯覚してしまいがちです。ですが、一般に非同期通信は render() 実行までに完了するとは限りません。例えば下記のコードは、データフェッチに時間がかかる場合、 render() 実行時に this.state.items を参照できずエラーになってしまいます(コードは https://daveceddia.com/watch-out-for-undefined-state/ より引用)。

class Quiz extends Component {
  componentWillMount() {
    axios.get('/thedata').then(res => {
      this.setState({items: res.data});
    });
  }

  render() {
    return (
      <ul>
        {this.state.items.map(item =>
          <li key={item.id}>{item.name}</li>
        )}
      </ul>
    );
  }
}

正しく動作させるには、下記のようなコンストラクタを書いて、初期値を設定する必要があります。

  constructor(props) {
    super(props);
    this.state = {
      items: []
    };
  }

「Will」の代わりに「Did」を使うことで、書き手は事前にコンストラクタで state の初期化が必要なことを意識しやすいですし、読み手も「通信が完了するまでに初期値で一瞬描画されるんだな」ということが理解しやすくなります。

componentWillMount は2回実行されることがある

いわゆる isomorphic な設計の場合、componentWillMount() はサーバーサイドとクライアントサイドで計2回実行されてしまうそうです。これに関しては私が isomorphic について無知なため詳しく説明できません。すみません・・・。

所感

A と B の2つの機能のうちどちらを使うか悩んだとき、「A だと X が実現できるが B ではできないから」といった論理的な理由をつい求めがちですが、「A の方が人にやさしいから」という理由でもいいんだよなあ、という気づきを得ました。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした