1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

useState・useEffect・useMemoの違いと使い分け

Posted at

React を使っているとよく登場するフックがuseStateuseEffectuseMemo です。
これについてたくさんの記事があると思いますが,アウトプットとして書きます

useState

役割
コンポーネント内で「状態(state)」を持たせるためのフック。
状態が更新されるとコンポーネントが再レンダリングされます。

使うケース
入力フォームの値
APIから取得したデータを保持する

サンプル

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

  return (
    <div>
      <p>クリック数: {count}</p>
      <button onClick={() => setCount(count + 1)}>増やす</button>
    </div>
  );
}

useEffect

役割
副作用(side effects)を扱うためのフック。
コンポーネントのレンダリング後に「外部とのやりとり」や「初期処理」を行いたいときに使います。

使うケース
初回マウント時に API からデータを取得
イベントリスナーやタイマーの登録/解除
DOM の直接操作

サンプル

function Users() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then((res) => res.json())
      .then((data) => setUsers(data));
  }, []); // 初回マウント時のみ実行

  return (
    <ul>
      {users.map((u) => (
        <li key={u.id}>{u.name}</li>
      ))}
    </ul>
  );
}

useMemo

役割
「計算コストが高い処理」をキャッシュするためのフック。
依存配列の値が変わったときだけ再計算され、それ以外は前回の結果を再利用します。

使うケース
配列やオブジェクトの重い計算結果をキャッシュしたい
子コンポーネントへの props で毎回新しい参照が作られるのを避けたい

サンプル

function IncomeTotal({ rows }: { rows: { amount: number }[] }) {
  // rows が変わった時だけ合計を計算
  const total = useMemo(() => {
    console.log("計算したよ!");
    return rows.reduce((sum, row) => sum + row.amount, 0);
  }, [rows]);

  return <div>収入合計: {total}</div>;
}

もしuseMemoを使わなければ、レンダリングのたびにreduceが実行されます。
処理が軽ければ問題ありませんが、数千件のデータ処理やグラフ用データの整形など、重い計算を繰り返すとパフォーマンスが悪化します。

useEffectとuseMemoの違い

どちらも依存配列を受け取って,依存が変わったときに「動く」イメージがあるが,用途と目的が違う.

useEffect の特徴

レンダリングが完了したあとに実行される
主に外部とのやりとりを扱う
戻り値は使えない(=return した値は次回に引き継げない)

useMemo の特徴

レンダリングの最中に実行される
主に「計算コストが高い処理の結果」をキャッシュする
戻り値をそのまま変数として利用できる

使い分けの基準まとめ

フック 主な用途 具体例
useState UIに反映させたい値の管理 入力値、モーダル開閉、API結果の保持
useEffect 副作用の処理(外部とのやりとり) データフェッチ、イベント登録、DOM操作
useMemo 計算コストの高い処理のキャッシュ 集計、フィルタリング、グラフ用データ生成

実際のケーススタディ

例えば「家計簿アプリの月次サマリー」を作るとします。
APIから収支データを取得する → useEffect
API結果を保持してUIに表示する → useState
データから合計・収支を計算する → useMemo(データ量が多いなら)

useEffect(() => {
  fetch("/transactions/summary")
    .then((res) => res.json())
    .then((data) => setRows(data));
}, []);

const incomeTotal = useMemo(() => calculateIncome(rows), [rows]);
const expenseTotal = useMemo(() => calculateExpense(rows), [rows]);
const balance = useMemo(() => incomeTotal - expenseTotal, [incomeTotal, expenseTotal]);

まとめ

useState:UIに反映させたい「状態」を持たせる
useEffect:データフェッチや外部処理など「副作用」を扱う
useMemo:計算結果をキャッシュして「無駄な再計算を避ける」

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?