1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ReactのuseState入門 — 画面の状態を管理する

1
Posted at

ReactのuseState入門 — 画面の状態を管理する

はじめに

Reactで「ボタンを押したらカウントが増える」「入力フォームの値を保持する」といった動きを実現するには State(状態) の管理が必要です。

関数コンポーネントでStateを扱うフックが useState です。


useStateの基本

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // 初期値は0

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

useState は配列を返します。

const [状態の値, 更新関数] = useState(初期値);
  • count:現在の値(読み取り専用)
  • setCount:値を更新する関数
  • 0:初期値

なぜ普通の変数ではダメなのか

// NG: これでは画面が更新されない
function Counter() {
  let count = 0;

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => { count++; }}>+1</button>
    </div>
  );
}

Reactは「Stateが変化した時」だけ再描画します。普通の変数を変えても再描画が走らないため、画面に反映されません。

setCount を呼ぶ → Reactが再描画を検知 → 画面が更新される という流れが重要です。


Stateの更新は直接変更ではなく置き換え

// NG: Stateを直接変更する(再描画されない)
count = count + 1;

// OK: setXxx()で新しい値を渡す
setCount(count + 1);

オブジェクトや配列の場合も同様です。

const [user, setUser] = useState({ name: '田中', age: 25 });

// NG: プロパティを直接変更
user.age = 26;

// OK: スプレッド演算子で新しいオブジェクトを作る
setUser({ ...user, age: 26 });
const [list, setList] = useState([1, 2, 3]);

// NG: pushで直接追加
list.push(4);

// OK: 新しい配列を作って渡す
setList([...list, 4]);

前の値を使って更新する

ボタンを連続クリックするような場合、前の値に依存して更新する時は関数形式を使います。

// 関数形式(推奨)
setCount(prev => prev + 1);

// 値形式(非推奨:連続更新で問題が起きることがある)
setCount(count + 1);

複数のStateを持つ

function Form() {
  const [name, setName] = useState('');
  const [age, setAge] = useState(0);
  const [isAdmin, setIsAdmin] = useState(false);

  return (
    <form>
      <input value={name} onChange={e => setName(e.target.value)} />
      <input type="number" value={age} onChange={e => setAge(Number(e.target.value))} />
      <input type="checkbox" checked={isAdmin} onChange={e => setIsAdmin(e.target.checked)} />
    </form>
  );
}

関連するStateはオブジェクトにまとめることもできます。

const [form, setForm] = useState({ name: '', age: 0 });

// 特定のフィールドだけ更新
setForm(prev => ({ ...prev, name: '田中' }));

Javaエンジニアがつまずくポイントまとめ

よくあるミス 正しい書き方
count++ で更新 setCount(count + 1)
user.age = 26 で更新 setUser({ ...user, age: 26 })
list.push(item) で追加 setList([...list, item])
値形式で連続更新 関数形式 prev => prev + 1 を使う

まとめ

  • useState でStateを宣言し、setXxx で更新する
  • Stateを更新すると自動で再描画される
  • Stateは直接変更せず、常に新しい値/オブジェクトを渡す
  • 前の値に依存する更新は関数形式 prev => ... を使う

次回は useEffect で副作用処理(データ取得・タイマーなど)の扱い方を整理します。

1
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?