useState vs useRef: 迷ったらコレ!それぞれの役割と使い分け

2024-04-21

React: useState と useRef の違い

useState は、コンポーネントの状態を管理するために使用されます。状態は、時間とともに変化するデータであり、コンポーネントのレンダリングに影響を与えます。

useRef は、DOM 要素への参照や、コンポーネント内で状態を保持するために使用されます。参照は、DOM 要素への直接的なアクセスを提供し、状態は、コンポーネントの再レンダリングをトリガーせずに保持することができます。

使い分けるポイント

  • useState を使用するケース:
    • コンポーネントの状態を管理したい場合
    • 状態の変化がコンポーネントのレンダリングに影響を与える場合
    • 例: 入力フォームの値、タイマーのカウントダウンなど
  • useRef を使用するケース:
    • DOM 要素への直接的なアクセスが必要な場合
    • コンポーネント内で状態を保持したいが、その状態がコンポーネントの再レンダリングをトリガーする必要がない場合
    • 例: フォームの入力フィールドへのフォーカス、アニメーションの実行など

useState と useRef の比較表

機能useStateuseRef
目的コンポーネントの状態を管理DOM 要素への参照、状態の保持
状態の変化コンポーネントの再レンダリングをトリガーコンポーネントの再レンダリングをトリガーしない
使用例入力フォームの値、タイマーのカウントダウンフォームの入力フィールドへのフォーカス、アニメーションの実行

具体的なコード例

useState

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>カウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>カウントアップ</button>
    </div>
  );
}

useRef

import React, { useRef } from 'react';

function InputFocus() {
  const inputRef = useRef(null);

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={focusInput}>フォーカス</button>
    </div>
  );
}



useStateを使ったカウンター

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>カウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>カウントアップ</button>
    </div>
  );
}

useRefを使ったフォーカス

この例では、useRefフックを使用して、ボタンをクリックすると入力フィールドにフォーカスを設定します。

import React, { useRef } from 'react';

function InputFocus() {
  const inputRef = useRef(null);

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={focusInput}>フォーカス</button>
    </div>
  );
}

useRefを使ってDOM要素にアクセス

import React, { useRef } from 'react';

function ButtonColorChange() {
  const buttonRef = useRef(null);

  const changeColor = () => {
    buttonRef.current.style.backgroundColor = 'red';
  };

  return (
    <div>
      <button ref={buttonRef} onClick={changeColor}>ボタンの色を変更</button>
    </div>
  );
}

これらの例は、useStateuseRefフックの基本的な使い方を示しています。これらのフックを組み合わせることで、さまざまな複雑な機能を実現することができます。




Reactにおける状態管理のその他の方法

  • useContext: コンポーネントツリー全体で共有される状態を管理するために使用されます。
  • useReducer: 複雑な状態ロジックを管理するために使用されます。
  • Redux: アプリケーション全体の状態を管理するためのライブラリです。
  • MobX: 状態管理のための別のライブラリです。

これらの方法はそれぞれ異なるユースケースに適しています。状況に応じて適切な方法を選択することが重要です。

具体的なユースケース

  • useContext:
    • ユーザー設定やテーマ設定など、アプリケーション全体で共有される状態を管理する場合
    • 例: ログイン状態、ダークモード設定など
  • useReducer:
    • フォームデータやゲームの状態など、複雑な状態ロジックを管理する場合
    • 例: ショッピングカート、Todoリストなど
  • Redux:
  • MobX:

useStateuseRef は、React で状態を管理するための基本的なフックですが、他にもさまざまな方法があります。それぞれの方法の特徴を理解し、状況に応じて適切な方法を選択することが重要です。


reactjs react-hooks


useState、useRef、useContext、useReducer:Reactフォーム要素の状態管理を徹底解説

この方法は、フォーム要素の状態をローカルに保持し、useState フックを使用して兄弟/親要素に渡します。この方法はシンプルで分かりやすいですが、フォーム要素が増えるとコードが冗長になりがちです。この方法は、useContext フックを使用して、フォーム要素の状態をコンポーネントツリー全体で共有します。...


React vs Angular: データバインディング徹底比較!一方通行と双方向のメリット・デメリットをわかりやすく解説

Reactは一方通行データバインディングを採用しており、データの流れはモデル(Model)からビュー(View)へと一方方向に進みます。一方、Angularは双方向データバインディングを採用しており、モデルとビューの間で双方向にデータの流れが発生します。...


switchステートメントを使用する

三項演算子を使用する利点:簡潔に記述できる読みやすいネストが深くなると複雑になり、可読性が低下する条件分岐用の関数を作成するコードを分割して整理できる可読性が高くなるコード量が増えるフラグメントを使用する条件分岐が分かりやすい複雑な条件分岐には不向き...


【初心者向け】ReactのuseStateフックとContext APIでコンポーネント間ステート共有をマスターしよう

コンポーネント間ステート共有には、主に以下の3つの方法があります。それぞれの方法には一長一短があり、状況に応じて最適な方法を選択する必要があります。useStateフックとContext APIを組み合わせることで、柔軟かつ効率的なステート共有を実現することもできます。...


JavaScript、React、React Hooksにおける「Uncaught Error: Rendered fewer hooks than expected」エラー:詳細な解決策と予防策

原因このエラーは、React Hooks 関数 (useState、useEffect など) の呼び出し数が、前回のレンダリング時の呼び出し数よりも少ない場合に発生します。React Hooks は、コンポーネントの状態と副作用を管理するために使用される関数です。React は、これらのフックがレンダリング中にどの順序で呼び出されたかを追跡し、その情報を使用してコンポーネントの状態を更新します。...


SQL SQL SQL SQL Amazon で見る



React 18の新機能 useIdフックでフォームラベルを一意に識別

React 18から導入されたuseIdフックを使うと、簡単に一意のIDを生成できます。useIdフックは、コンポーネント内で一意のIDを生成し、id変数に格納します。このIDをfor属性に設定することで、ラベルと入力フィールドを関連付けられます。