Yanonoblog!

こつこつと

useEffectを最新のReactドキュメントから学ぶ

はじめに

本記事では「モダンJavaScriptの基本から始める React実践の教科書」で学んだ内容と別途気になって調べた内容や知識も含めアウトプットしています。

詳細は2023年の3月にリリースされた新しいReactの公式ドキュメントを参照してまとめています。

書籍に記載されている内容を順序立ててまとめるというよりは、整理しておきたい周辺の知識と深ぼった内容を雑多に書いています。

超基礎的な内容です!

レンダリング

Reactでは、コンポーネントの状態やプロパティが変更された場合、それに応じてコンポーネントが再度レンダリングされます。

レンダリングのトリガーとなる要因は、状態の変更やプロパティの変更だけでなく、親コンポーネントの再レンダリングコンポーネントのマウントやアンマウントなども含まれます。Reactはこれらの変更を検知し、必要な場合に再レンダリングをトリガーすることで、柔軟で効率的なUIの構築を実現しています。

useEffect

useEffectは、コンポーネントの副作用を制御する機能です。

依存している”ある値が変わったときに限り、ある処理を実行する”ということです。

// import
import { useEffect } from 'react';

// 基本構文
useEffect(副作用の処理, [依存する値])

useEffectの第一引数には副作用の処理を含む関数を指定します。

この関数はコンポーネントレンダリング後に実行されます。

useEffectの第二引数には依存関係の配列を指定します。この配列に含まれる値が変更された場合にのみ副作用の処理が再実行されます。

依存関係が指定されていない場合は、コンポーネントレンダリングごとに副作用の処理が実行されます。

コード例

副作用の中で、count の値が 10 になった場合にアラートを表示しています。

count が 10 になると、alert("10になりました") が実行されます。

import "./styles.css";
import React, { useEffect, useState } from 'react';

export default function App() {
  const [count, setCount] = useState(0)
  useEffect(() => {
    if (count === 10) {
      alert("10になりました");
    }
  }, [count]);

  return (
    <div className="App">
      <h1>useEffect Test</h1>
      <h3>count: {count}</h3>
      <button onClick={() => setCount(prevNum => prevNum + 1)}>PLUS</button>
    </div>
  );
}

このような実装であればuseStateだけで十分なのですが、、

補足

  • useEffectはフックなので、コンポーネントまたは独自のフックの最上位でのみ呼び出すことができます。 ループまたは条件内で呼び出すことはできません。 必要な場合は、新しいコンポーネントを抽出し、そこに状態を移動します。
  • useEffectはクライアントでのみ実行されます。サーバーレンダリング中には実行されません。
  • useEffectがユーザーの操作(クリックなど)によるものでない場合、Reactはブラウザが画面を更新する前にuseEffectを実行します。 もしuseEffectが視覚的な操作を行っている場合で、遅延が目に見える場合は、useEffectuseLayoutEffectに置き換えてみると良いそうです。

useEffectが必要でないケース

公式ドキュメントに記載されていた内容を解釈してまとめます。

https://react.dev/learn/you-might-not-need-an-effect

データ変換のためにuseEffectは必要ない

リストを表示する前にフィルタリングしたい場合、リストが変更されるたびにuseEffectを使用して状態変数を更新するのは実は非効率です。

  1. 関数コンポーネントの呼び出すため画面上に表示すべき内容を計算
  2. これらの変更をDOMに「コミット」し、画面を更新。
  3. useEffectの処理を実行

useEffectが状態を更新する場合、上記のプロセスがやり直されてしまいます。

過度なレンダリングを回避するためには、コンポーネントのトップレベルですべてのデータを変換します。

そうすることでプロパティや状態が変わるたびに、コードは自動的に再実行されます。

ユーザーイベントの処理にuseEffectは必要ない

ユーザーが商品を購入したときに/api/buyのPOSTリクエストを送信し、通知を表示したいケースが例として挙げられていました。

購入ボタンのクリックイベントハンドラでは、何が起こったかを正確に把握できます。

一方、useEffectが実行される時点では、ユーザーが何をしたか(例:どのボタンがクリックされたか)は分かりません。

そのため、通常はユーザーイベントは対応するイベントハンドラ内で処理することが一般的です。

参考

続く…

コメント

本記事の内容は以上になります!

書籍の続きのアウトプットも随時更新したいと思います。


プログラミングスクールのご紹介 (卒業生より)

お世話になったプログラミングスクールであるRUNTEQです♪

https://runteq.jp/r/ohtFwbjW

こちらのリンクを経由すると1万円引きになります。

RUNTEQを通じて開発学習の末、受託開発企業をご紹介いただき、現在も双方とご縁があります。

もし、興味がありましたらお気軽にコメントか、TwitterのDMでお声掛けください。

https://twitter.com/outputky