📌

useStateフックとuseRefフックの違い

2024/03/12に公開

Reactで開発していく中でフックはよく使うものだと思いますが、useStateフックとuseRefフックの違いがピンときていなかったので両者の違いについてまとめておきます。

useState

useStateフックはコンポーネントの状態を管理するために使われます。
useStateに設定された値が変化した場合、Reactはコンポーネントを再レンダリングします。
値が変化した際に再レンダリングされるというのがポイントで、カウンターなどの値が変化した際に即座にUIに反映しなければならない場合に適しています。

useRef

useRefフックはコンポーネント内で参照(ref)を保持するためのフックです。
主にDOMの参照の保持を目的に利用されますが、任意の値を保持するために使うこともできます。
useRefで保持した値は普通の変数とは異なり、コンポーネントが再レンダリングされた際にも保持されます。
またuseStateに保持している値とは異なり、値が更新されてもコンポーネントが再レンダリングされることはありません。

両者の違い

値が更新された際にコンポーネントの再レンダリングが行われるかどうかが最大の違いです。
そのため、ここを認識せずにuseStateばかり使っているとコンポーネントの思わぬ再レンダリングに苦しめられることになります。
useStateはあくまでコンポーネントの状態の管理に使われるということを認識し、コンポーネントを再レンダリングしたくない場合はuseRefフックを使うようにしましょう。
また、useRefフックはコンポーネントが再レンダリングされた際に値が更新されないため、再レンダリングの際に値を初期値に戻したい場合などは普通の変数を利用するのが無難でしょう。

useRefのDOM参照について

おまけとして、useRefフックのDOM参照についても記載しておきます。
useRefフックの重要な機能として、DOMへの参照の保持というものがあります。
例えばテキストフィールドに設定された値を常に監視し、最新の状態を取得すると言ったことができます。
以下はその例です。

import React, { useRef, useEffect } from 'react';

function TextInputWithFocus() {
  // `useRef`を使ってテキスト入力のためのrefを作成します。
  const inputEl = useRef(null);

  useEffect(() => {
    // コンポーネントがマウントされた後にテキスト入力に自動的にフォーカスを当てます。
    inputEl.current.focus();
  }, []);

  return (
    <div>
      {/* `ref`属性に`inputEl`を割り当てることで、このinput要素への参照を`inputEl`に保持させます。 */}
      <input ref={inputEl} type="text" />
      <button onClick={() => inputEl.current.focus()}>
        フォーカスを当てる
      </button>
    </div>
  );
}

この例ではinput要素にinputElというuseRefフックを設定しています。
これで、inputElを通じて常にこのテキスト入力の値を取得することができるようになります。
また、.current.focus()メソッドを使うことでテキスト入力に直接フォーカスを当てることもできます。

Discussion