JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

Reactライフサイクルとは?3つのフェーズと主要メソッドをわかりやすく解説

Reactにおけるライフサイクルは、「マウント(mounting)」「更新(updating)」「アンマウント(unmounting)」という3つのフェーズに分けて考えることができます。マウントとは、ReactコンポーネントがDOM(Document Object Model)に描画される段階のことです。そのコンポーネントに変更が加えられると、更新フェーズへと移行します。

更新フェーズでは、一連の内部メソッドが実行され、新しい情報の有無が確認され、コンポーネントが再レンダリングされます。そしてアンマウントとは、単純にコンポーネントがDOMから削除されることを指します。

本記事では、ライフサイクル全体の概要と、よく使われる主要なメソッドについて解説します。ここで取り上げる以外にも多数のライフサイクルメソッドが存在するため、詳細はReact公式ドキュメントも併せて参照してください。

Reactライフサイクルとは?

コンポーネントがDOMに読み込まれると、まず最初のフェーズである「マウント」に入ります。このフェーズでは、コンポーネントが定義された通りの形でレンダリングされます。これにより、ユーザーとのやり取りが可能な状態になり、第2フェーズへと進みます。

第2フェーズでは、ユーザーがコンポーネントに対して何らかの操作を行い、変更が発生しています。多くの場合、これはユーザーのアクションによってコンポーネントのstate(状態)が変化したことを意味します。ここからが更新フェーズです。

更新フェーズでは、Reactは変更内容を画面に反映するためにコンポーネントを再レンダリングします。たとえばstateの変更によって更新フェーズがトリガーされた場合、setState()メソッドが呼び出され、初期stateが変更されて再レンダリング処理が開始されます。

最後に、特定のコンポーネントから離れる(ページ遷移するなど)際には、そのコンポーネントをDOMから削除できます。これが「アンマウント」であり、ライフサイクルの第3フェーズです。必須ではありませんが、コンポーネントを多用するアプリケーションでは、パフォーマンス向上のため実装が推奨されます。

よく使われるライフサイクルメソッド

Reactコンポーネントのライフサイクルの流れを理解したところで、次によく使われるライフサイクルメソッドを見ていきましょう。ライフサイクルメソッドとは、ライフサイクルの各段階でReactが自動的に呼び出すメソッドのことです。必須のものと任意のものがあり、ここでは必須メソッドと、特によく使われる任意メソッドを紹介します。

マウント(Mounting)

クラスコンポーネントをマウントする際、最初によく使われる任意メソッドがconstructor()です。constructorメソッド内では、コンポーネントの初期stateを直接宣言できます。

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      currentUser: " "
    }
  }
}

この例では、現在のユーザーを表す値を初期stateとして設定しています。constructor()メソッドには、お決まりのsuper()メソッドが必要です。

ここでは、コンポーネントがマウントされた時点ではまだ誰もログインしていないものと仮定します。ユーザーがログインできるようにするには、ログインフォームが必要です。そこで登場するのが、最初の必須メソッドであるrender()です。

コンポーネントのマウントにおいて必須となるのがrender()メソッドです。クラスコンポーネントが構築され、初期stateが設定された後、別のコンポーネントまたはHTMLをレンダリングできます。

render() {
  return (
    <LoginForm />
  )
}

render()のreturn文の書き方は、他のメソッドとは少し異なります。returnの後に波括弧ではなく丸括弧を使う点に注目してください。このreturn文では、LoginFormコンポーネントをレンダリングしています。

ユーザーがログインすると、認証情報にアクセスできるようになります。実際のアプリケーションでは、ログイン時にサーバーへfetchリクエストを送信し、一致する認証情報を取得します。ただし、本記事はライフサイクルの入門編なので、ここではstateを直接設定することにします。

このシンプルな例では、Johnというユーザーがパスワードを入力し、ログインボタンを押します。サーバーへのfetchリクエストが送られ、サーバーはJohnの認証情報を返します。Johnがログインできたら、彼が自分でログアウトするまでログイン状態を維持したいところです。

そのために使えるのが、よく使われる任意メソッドcomponentWillMount()です。このライフサイクルメソッドが呼び出されると、コンポーネントのレンダリング後に実行されます。新しいstateを設定するのに適した場所です。

componentWillMount() {
  this.setState({
    currentUser: "John"
  })
}

これで、コンポーネントのレンダリング後、マウント完了前に、currentUserとして「John」がstateに設定されます。ページをリフレッシュしてもstateにはJohnが設定されているため、ユーザーはログイン状態を保てます。

なお、componentWillMount()はReact 16.3以降で非推奨(deprecated)となっており、現代の開発ではcomponentDidMount()getDerivedStateFromProps()の使用が推奨されています。ただし、ライフサイクルの流れを理解するうえで、この例は依然として参考になります。

setState()メソッドの使用は、ライフサイクルの更新フェーズへの入り口でもあります。setState()が呼び出されると、Reactに対してコンポーネントに変更があったことが通知されます。Reactはユーザーに変更を表示するため、コンポーネントを再レンダリングします。この例では、Johnがログインしていることが表示されます。

更新(Updating)

ライフサイクルの更新ステージには、この入門記事の範囲を超える多数の任意ライフサイクルメソッドが存在します。ここでは、変更が検知されると(通常はsetState経由)、Reactが必須メソッドであるrender()を再度呼び出し、コンポーネントが変更内容を反映して再レンダリングされる、ということだけ押さえておけば十分です。

アンマウント(Unmounting)

コンポーネントのライフサイクルの最終ステージが「アンマウント」です。ここでコンポーネントはDOMから削除されます。必須ではありませんが、コンポーネントを多用するアプリケーションのパフォーマンス向上に役立ちます。

アンマウントには任意メソッドが1つだけ存在します。それがcomponentWillUnmount()です。先ほどのユーザーJohnがログアウトしたい場合、ログアウトボタンをクリックしたタイミングでcomponentWillUnmount()を使い、彼のユーザープロフィールをDOMから削除できます。

以下の例はやや単純化していますが、ライフサイクルの各ステージで何が起きているのかを明確に示しています。

class UserContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      currentUser: " "
    }
  }
  componentWillMount() {
    this.setState({
      currentUser: "John"
    })
  }

  logout = () => {
    this.setState({
      currentUser: " "
    })
  }

  render() {
    if (this.state.currentUser === "John") {
      return (
        <div>
          <UserProfile />
          <button type="button" onClick={this.logout}>Logout</button>
        </div>
      )
    } else {
      return (
        <button type="button">Login</button>
      )
    }
  }
}

class UserProfile extends React.Component {
  componentWillUnmount() {
    alert("Logged Out")
  }
  render() {
    return (
      <h1>Welcome back, John!</h1>
    )
  }
}

ここには2つのコンポーネントがあります。1つ目はUserContainerで、UserProfileコンポーネントを保持しています。UserProfileにはユーザー情報が含まれています。

UserContainerでは、前述のとおりコンポーネントを構築し、初期stateを設定します。コンポーネントは一瞬だけログインボタン付きでレンダリングされます。コンポーネントがマウントされる直前に、Johnとしてログインします。これによりReactはコンポーネントを更新し、Johnの認証情報とともに再レンダリングします。

Johnがログインしたら、UserProfileコンポーネントをレンダリングします。ここにはJohnのユーザー情報がすべて含まれているため、ログアウトした時点で速やかにDOMから削除する必要があります。

ログアウトボタンがクリックされると、logout関数が実行され、currentUserが空文字列の初期stateに戻ります。logout関数内でsetStateが呼び出されるため、Reactはコンテナコンポーネントを再レンダリングします。その結果、UserProfileコンポーネントは表示されなくなり、ユーザーには「ログアウトしました」というポップアップアラートが表示されます。

まとめ

Reactのライフサイクルには、ここで取り上げた以上の内容があります。本記事の目的は、シンプルなコード例とともに基本概念を紹介することです。ライフサイクルの概念を理解した今なら、React公式ドキュメントもより読みやすくなっているはずです。

本ガイドと関連記事を読めば、Reactにおけるライフサイクルとは何かをつかみ、さらに自力で深掘りしていく力が身についたはずです。プログラミングの複雑な概念すべてに言えることですが、日々の練習こそが細部を習得する近道です。

  1. React NativeのVirtualizedListコンポーネントの使い方を徹底解説

    VirtualizedListコンポーネントは、非常に大量のデータを扱うリストの表示に最適なコンポーネントです。VirtualizedListを活用することで、パフォーマンスの向上とメモリ使用量の効率化を実現できます。ユーザーがスクロールするのに合わせて、必要なデータだけが順次表示される仕組みになっています。VirtualizedListの基本的な構成は以下の通りです。<VirtualizedList  data={DATA}  initialNumToRender={4}  renderItem={renderItem}&nb

  2. Androidストレージ入門:内部ストレージと外部ストレージの違いと使い分け

    ストレージは誰もが知っている存在でありながら、ついその重要性を見過ごしてしまいがちなものです。かつてはストレージ容量のわずかな増加さえも大きな飛躍であり、実現不可能に思えることさえありました。しかし今では、デバイスにどれだけの容量があるかを気にする人はほとんどいません(その違いに関心を持つ人はさらに少ないでしょう)。 より重要なのは、ストレージに保存されるデータの変遷に目を向けることです。スマートフォン以前の時代、私たちが保存していたのはたまに撮影した写真数枚、いくつかのゲーム、そして大量のテキストメッセージ程度でした。しかし現在、標準的なスマートフォンには、アプリケーション、ドキュメント、写