【Reactの設計を学ぶ】ライフサイクルを知ろう

はじめに

この記事ではReactのライフサイクルについて紹介します。

ライフサイクルとライフサイクルメソッドは開発において設計を理解するためにも非常に重要です。
ここで一度概略を掴んでおくと、自分で必要になった時に理解が進むと思います。

イメージしにくいかもしれませんが、ぜひ通読してみて下さい。

対象読者は以下のことが理解できている方です。

  • JSXを使った簡単な画面のレンダリング
  • stateやpropsの使い方
  • コンポーネントのimportやexportの仕組み

全くReactを知らない方は、まずこちらを読んでみてください。

React.jsを始めよう:動かしながら仕組みを知ろう

公式のリファレンスはこちらです。

公式のチュートリアル

目次

Reactのライフサイクルとは

component-intervals

Reactのコンポーネントにはライフサイクル(lifecycle)と呼ばれる時間の流れがあります。
イメージとしては日が昇り、日中に活動し、夜になり就寝するという感じです。

このライフサイクルは3つの状態を遷移します。
それはMountingUpdateingUnmoutingの3つです。
具体的には以下のようなものです。

タイミングと内容時間帯に例えると…
Mountingコンポーネントがユーザーにレンダリングされるまでの仕込みの期間日の出
Updatingコンポーネントがユーザに表示されており、ユーザーが操作できる期間日中
Unmouting他のコンポーネントに切り替え前に現在表示されているコンポーネントを破棄するための期間日暮れ

それぞれの段階にはその時に使えるものが定義されています。
次に紹介します。

ライフサイクルメソッドとは

上で説明したライフサイクルにはそれに付随したライフサイクルメソッドというものがあります。
これらのメソッドはライフサイクルに合わせて順番に呼ばれます。

ただし、これらはクラスベースのコンポーネントでしか使用できないことに注意してください。

(補足):関数ベースコンポーネントとクラスベースコンポーネント

// function based component
import React from 'react';

const welcome = (props) => {
  return <h1>Hello, {props.name}</h1>
}
// class based component
import React, { Component } from 'react';

class Welcome extends Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

先程、ライフサイクルメソッドはクラスベースコンポーネントでしか使用できないと説明しましたが、関数ベースのコンポーネントでは新機能があり、useEffect()というフックで一部代用できます。

これは後に説明するcomponentDidMount, componentDidUpdate, componentWillUnmountが3つ合わさったようなものです。

興味がある方は以下を参照してください。

React Document:副作用フックの利用法

ライフサイクルメソッドの流れ

ライフサイクルメソッドには呼ばれる順番とその役割があります。
MountingUpdateingUnmouting時によばれる主なものには以下があります。

Mounting

lifecycle-mounting

constructor()

Mounting時に一番最初に呼ばれるメソッドです。

JSXでは使われることがほとんどないため、見かけることもまれです。
super(props)を呼び、更新がする必要性があれば更新できます。

getDerivedFromProps()

このメソッドだけはstaticです。

render()が呼ばれる前にstateの更新があるかどうかを確認します。
もしあれば更新後のstate、無ければnullを返します。

render()

このメソッドだけはコンポーネントで必須です。

ReactがJSXコードを評価して、仮想DOMを構築します。

componentDidMount()

このメソッドは重要なライフサイクルメソッドの一つです。

クラスベースのコンポーネントを操作する時に非常に多く使用します。
1回目のrender()が呼ばれた時に1度だけ呼ばれ、ネットワークへのリクエストなどはこのメソッド内で行います。

Update

lifecycle-updating

getDerivedStateFromProps()

Update時に一番最初に呼ばれるメソッドです。

コンポーネントのstateを初期化します。
ただし、使用頻度は低いです。

shouldComponentUpdate()

コンポーネントの評価と再レンダリングを継続するかどうかを決定します。
つまり更新をここでキャンセル出来ます。

ただし、更新をブロックするとコンポーネントが破損する可能性があるので慎重に使う必要があります。

render()

上記と同様にレンダリングするメソッドです。

これも必須のメソッドです。

getSnapshotBeforeUpdate()

更新が発生する直前のスクロールを位置を記憶して、提供するような使い方が出来ます。

このメソッドも使用頻度は低いです。

componentDidUpdate()

更新が完了した際に呼ばれるメソッドです。

HTTPリクエストを作成できますが、無限ループにならないように注意する必要があります。

Unmouting

lifecycle-unmouting

componentWillUnmount()

コンポーネントがUnmountされるときに呼ばれるメソッドです。

アニメーションなどを設定した場合はここで破棄します。
それにより次に新しいコンポーネントのサイクルが始まった際にも、その分のリソースを削減できます。

Mounting時のライフサイクルメソッドの実行

メソッドの呼ばれる順番とそれぞれの役割について説明しました。

最後にMounting時のライフサイクルメソッドが呼ばれる過程を実際にコンソールに出力させて確認してみます。
以下のコードをReactのApp.jsに記述し、実際にコンパイルしてみます。

import React, { Component } from 'react';

class App extends Component {
  // constructor
  constructor(props) {
    super(props);
    console.log('[App.js] constructor');
  }

  state = {
    persons: [
      { name: 'Ayano', age: 22 },
      { name: 'Yuka', age: 21 },
      { name: 'Ayaka', age: 21 }
    ],
  };

  // getDerivedStateFromProps
  static getDerivedStateFromProps(props, state) {
    console.log('[App.js] getDerivedStateFromProps', props);
    return state;
  }

  // componentDidMount
  componentDidMount() {
    console.log('[App.js] componentDidMount');
  }

  // render
  render() {
    console.log('[App.js] render');

    return (
      <div>
        <h1>This is App.js</h1>
        <p>React lifecycle method description</p>
        <ul>
          <li>{this.state.persons[0].name}</li>
          <li>{this.state.persons[1].name}</li>
          <li>{this.state.persons[2].name}</li>
        </ul>
      </div>
    );
  }
}

export default App;

すると以下のようにレンダリングされると同時に、呼ばれたメソッド名もコンソールに出力されます。

rendering

Consoleにcontructor → getDerivedStateFromProps → render → componentDidMountの順に出力されています。

今回はこれらのメソッドに機能を追加しているわけでないですが、実際にライフサイクルが存在することは確認できました。

まとめ

ライフサイクルライフサイクルメソッドについて紹介しました。

実際に使う時にならないとなかなかイメージが湧きづらいかもしれませんが、概要をつかめればこれからの開発時に役立つはずです。

これからReactを学んでみたい方の一助になれば幸いです。

React.jsに関する他の記事を見る↓↓

https://code-ship-blog.wemotion.co.jp/technology/%e3%80%90react%e3%80%91%e3%82%a2%e3%83%97%e3%83%aa%e9%96%8b%e7%99%ba%e3%82%aa%e3%82%b9%e3%82%b9%e3%83%a1%e8%a8%98%e4%ba%8b%e3%81%be%e3%81%a8%e3%82%81%ef%bc%81%e8%a8%80%e8%aa%9e%e3%83%bbfw%e3%81%ae/

参考文献・URL

stateとライフサイクル

https://ja.reactjs.org/docs/state-and-lifecycle.html#___gatsby

React(v16.4) コンポーネントライフサイクルメソッドまとめ

https://qiita.com/Julia0709/items/3c3fc8d29fd2e56ed7a9

React コンポーネントのライフサイクルとメソッドの役割について

https://qiita.com/koseki/items/432cd54b37cf44865dbd

What does Side effects mean in React?

https://www.reddit.com/r/reactjs/comments/8avfej/what_does_side_effects_mean_in_react/


おすすめ記事

https://code-ship-blog.wemotion.co.jp/technology/%e3%80%90python%e3%82%a2%e3%83%97%e3%83%aa%e9%96%8b%e7%99%ba%e5%85%a5%e9%96%80%e3%80%91%e4%bb%8a%e3%81%99%e3%81%90%e5%a7%8b%e3%82%81%e3%82%89%e3%82%8c%e3%82%8b%e9%96%8b%e7%99%ba%e7%92%b0%e5%a2%83/
https://code-ship-blog.wemotion.co.jp/technology/%e3%80%90web%e3%83%9a%e3%83%bc%e3%82%b8%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e5%85%a5%e9%96%80%e3%80%91-jquery%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/
https://code-ship-blog.wemotion.co.jp/technology/%e3%80%90%e3%82%a2%e3%83%97%e3%83%aa%e9%96%8b%e7%99%ba%e3%80%91%e3%83%86%e3%82%b9%e3%83%88%e7%94%a8api%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%83%ac%e3%82%a4%e3%82%a2%e3%82%a6%e3%83%88%e3%82%92/