【React Hooks】ライフサイクルについて


概要

 reactのライフサイクルを扱うフックuseEffectについて学んだことを共有する。

ライフサイクルとは

 ライフサイクルとはコンポーネントの処理の流れを表しています。コンポーネントがいきなり画面に表示されるのではなく、constructorをコールして、render()をコールしてなど、手順を踏んでユーザーの画面に情報を描画されます。この処理の流れのことをライフサイクルと呼びます。

3つのライフサイクル

 Reactのclassで設定できるライフサイクルは大きく分けて3つの処理があります。

  • componetDidMount
  • componentDidUpdate
  • componentWillUnmount

です。それぞれ処理される順番を図にまとめると以下のようになります。

  • commponentDidMount

    • 一番始めのレンダーされた直後に一度だけコールされるメソッドです。
    • イベントリスナーの設定、API通信の記述などをする。
  • componentDidUpdate

    • コンポーネントが表示された後、ユーザーによる操作(クリック、スクロールなど)によって、再レンダーされた直後にコールされるメソッドです。
    • ユーザーが操作し、再レンダーするたびにコールされる。
  • componentWillUnmount

    • 画面遷移などして、コンポーネントが破棄される前にコールされるメソッドです。
    • イベントリスナーの解除、API通信の切断などに記述する。

useEffectについて

 関数コンポーネントでは、フックであるuseEffectを使用して、ライフサイクルを代替的に実現するのですが、まずuseEffectがどういったものなのかを述べます。useEffectは副作用フックと呼ばれ、副作用を実現することができます。データの取得や、DOMの操作などは適切な箇所で操作する必要があります。例えば、DOM操作に関して、レンダーした後ではないと、DOM操作はできません。レンダーする前にDOM操作するとDOMが生成されていないためエラーになります。そのようにライフサイクルにおいて適切な箇所に適切な処理を記述してあげることを副作用と呼びます。
 useEffectの使用例を以下に示します。基本の形は、useEffectの第一引数にコールバック関数を指定すると、レンダーされるたびにそのコールバック関数がコールされます。

useEffect.tsx
import {useEffect} from 'react';

userEfffect( () => {
  console.log('レンダーされるたびにコールされる');
]);

また、第二引数に配列を指定することができます。例えば、第二引数にvalueという変数を指定すると、valueの値が変更するたびにコールされます。第二引数を指定しても初回レンダー時は必ずコールされるため注意する必要があります。第二引数の配列の中を空白にすると、初回レンダー時にしかコールされません。

import {useEffect} from 'react';

userEfffect( () => {
  console.log('第二引数に指定された値が変化するたびにコールされる');
], [value]);
import {useEffect} from 'react';

userEfffect( () => {
  console.log('初回レンダー時のみコールされる');
], []);

returnにはクリーンアップ関数を指定することができます。クリーンアップ関数とは、コンポーネントが破棄される際にコールされる関数です。主にメモリの開放処理などを行うため、クリーンアップ関数と呼ばれます。注意してほしいのは、再レンダーされるたびに、前回のクリーンアップコンポーネントが実行されます。動きとしては、再レンダー→以前のクリーンアップ関数を実行→今回のuseEffectの第一引数のコールバック関数を実行となります。

import {useEffect} from 'react';

userEfffect( () => {
  return () => console.log('コンポーネントが破棄されるときにコールされる');
]);

フックによるライフサイクルの実現

 Reactのフックでは、useEffectを使用して前章で示したライフサイクルを代替的に実現することができます。

  • componentDidMount
example.tsx
import {useEffect} from 'react';

userEfffect( () => {
  console.log('componentDidMount');
], []);
  • componentDidUpdate
example.tsx
import {useEffect} from 'react';

userEfffect( () => {
  if(/* ユーザーの操作を指定 */'){
    console.log('componentDidUpdate');
  }
]);
  • componentWillUnmaout
example.tsx
import {useEffect} from 'react';

userEfffect( () => {
  return () => {
    console.log('componentWillUnmount');
  }
]);

活用例

 componentDidMountcomponentDidUpdateの処理が同じで、componentWillUnmountも指定するのであれば、以下のように記述することで実現できる。

example.tsx
import {useEffect} from 'react';

userEfffect( () => {
  console.log('componentDidMountとcomponentDidUpdate');
    return () => {
    console.log('componentWillUnmount');
  }
]);

あとは、以上のことを組み合わせることで自分が実現したい機能を実現すればよいです!

参考