zukucode
主にWEB関連の情報を技術メモとして発信しています。

React useEffectの後片付けでイベント登録を解除する

画面の幅が変わったときに表示を更新したい場合、ブラウザのresizeイベントを登録できます。登録したままにすると、コンポーネントが不要になったあとも処理が残るため、useEffectの後片付けを用意します。

登録と解除を対にする

import { useEffect, useState } from 'react';

export const WindowWidth = () => {
  const [width, setWidth] = useState(() => window.innerWidth);

  useEffect(() => {
    const update = () => setWidth(window.innerWidth);
    window.addEventListener('resize', update);

    return () => window.removeEventListener('resize', update);
  }, []);

  return <p>幅: {width}px</p>;
};

返した関数がcleanupです。コンポーネントが外れるときや、依存値が変わってEffectを再実行する前に呼ばれます。

cleanupが必要な処理を見分ける

イベント購読、タイマー、WebSocket接続など、コンポーネントの外側に残る処理には対応する解除が必要です。例えばタイマーなら以下のようにします。

useEffect(() => {
  const timer = window.setInterval(() => console.log('更新確認'), 1000);
  return () => window.clearInterval(timer);
}, []);

開発環境のStrict Modeでは、Effectのセットアップとcleanupが追加で実行されることがあります。そこで同じイベントが二重に動くなら、解除の不足を疑ってください。本番での実行回数を合わせるためにStrict Modeを外す必要はありません。

なぜ同じ関数を渡すか

removeEventListenerには、登録時と同じ関数を渡します。別の無名関数を作って渡しても解除できません。

この例はブラウザでのみ描画する画面を想定しています。SSRを使う場合は、初期値を固定し、ブラウザ上で動くEffect内で幅を取得する設計が必要です。


関連記事

  • TypeScript i18nextの動的な翻訳キーを抽出対象に含める

    i18nextでステータスに応じた文言を表示する場合、翻訳キーを動的に切り替えることがあります。ただし、実行時に正しく表示できることと、翻訳キーの抽出ツールが使用箇所を検出できることは別です。今回は、...


  • React useStateで入力フォームを作成する

    Reactでテキストボックスに入力した値を使用するには、useStateで値を保持します。今回は名前とメールアドレスを入力し、送信ボタンを押すと入力内容を表示するフォームを作成します。この例では入力値...


  • React useStateで一覧の追加と削除を行う

    Reactで一覧を表示するときは、配列をuseStateへ保存できます。今回は簡単な買い物リストを作り、項目の追加と削除を行います。配列のpushやspliceで既存のstateを直接変更するのではな...


  • React useEffectで無限ループが発生するときに確認すること

    ReactのuseEffectを利用したときに無限ループが発生してしまうことがあります。特に注意したいのが、ESLintのreact-hooks/exhaustive-depsで表示された警告をUpd...


  • React 関数コンポーネントにプロパティを設定する

    React+TypeScriptで作成した関数コンポーネントにプロパティを設定する方法を紹介します。以下は送信ボタンのコンポーネントを作成しています。isSubmittingというプロパティを用意して...


  • Reactで兄弟コンポーネントの状態を共有する

    検索欄に入力した文字列を、別の一覧コンポーネントでも使いたい場合があります。兄弟同士で別々にstateを持つと値がずれるため、共通の親にstateを置きます。入力欄は値を受け取り、変更を親へ通知します...


  • React useStateでselectの選択値を取得する

    Reactでプルダウンの選択値を扱うには、selectのvalueとonChangeを使用します。DOMから取得するvalueは、数値の選択肢を表示していても文字列です。選択値をそのまま識別子として扱...


  • React react-router-domの基本的な使い方

    React+TypeScriptのプロジェクトにreact-router-domを導入してSPAのアプリケーションを作成する方法を紹介します。まずはreact-router-domのパッケージをインス...


  • react-router-dom ページごとにファイルを分割する

    react-router-domでシングルアプリケーションを作成していると、ページ数が増えるにしたがって作成されるjsファイルのファイルサイズもどんどん増えていきます。ページごとにファイルを分割し、そ...


  • react-router-domでプログラムから画面遷移を行う

    react-router-domでプログラムから画面遷移を行う方法を紹介します。history.psuh(遷移先URL)の形式で実行すると、画面遷移を行えます。historyはreact-router...