React 速習チュートリアル

React useState Hook

1. useState

Reactの useState フック(Hook)を使用すると、関数コンポーネント(Function Component)内でステート(State)を追跡できるようになります。

ステートとは、一般的にアプリケーション内で追跡・管理が必要なデータやプロパティ(Property)のことを指します。

2. useStateのインポート

useState フックを使用するには、まずコンポーネントにインポート(Import)する必要があります。

2.1 インポートの実装例

コンポーネントの冒頭で useState フックをインポートします。

import { useState } from "react";

ここでは、react から useState をデストラクチャリング(分割代入)しています。これは useState がネームドエクスポート(Named Export)されているためです。

3. useStateの初期化

関数コンポーネント内で useState を呼び出すことで、ステートを初期化(Initialize)します。

useState は初期ステート(Initial State)を引数として受け取り、2つの値を返します:

  1. 現在のステート
  2. ステートをアップデート(更新)するための関数

3.1 初期化の実装例

関数コンポーネントの最上部でステートを初期化します。

import { useState } from "react";

function FavoriteColor() {
  const [color, setColor] = useState("red");
}

ここでも、useState から返された値をデストラクチャリングしています。

  • 最初の値である color が、現在のステートです。
  • 2番目の値である setColor が、ステートをアップデートするために使用される関数です。

これらの名前はバリアブル(Variable)ですので、任意の名前を付けることができます。
最後に、useState("red") とすることで、初期ステートを "red" にセットしています。

4. ステートの読み取り

初期化が終われば、コンポーネント内のどこでもステートを含めることができます。

4.1 読み取りの実装例

レンダリング(Rendering)されるコンポーネント内で、ステートバリアブルを使用します。

import { useState } from 'react';
import { createRoot } from 'react-dom/client';

function FavoriteColor() {
  const [color, setColor] = useState("red");

  return <h1>私のお気に入りの色は {color} です!</h1>
}

createRoot(document.getElementById('root')).render(
  <FavoriteColor />
);

5. ステートの更新

ステートをアップデートするには、ステートアップデート関数(State Updater Function)を使用します。

5.1 更新関数の使用例

アップデート関数を使用してステートを更新するコードです:

<button
  type="button"
  onClick={() => setColor("blue")}>青色にする</button>

注意: ステートを直接アップデートしてはいけません。例えば、color = "blue" のような記述は禁止されています。

5.2 ボタンによる更新の完全な例

import { useState } from 'react';
import { createRoot } from 'react-dom/client';

function FavoriteColor() {
  const [color, setColor] = useState("red");

  return (
    <>
      <h1>私のお気に入りの色は {color} です!</h1>
      <button
        type="button"
        onClick={() => setColor("blue")}
      >青色にする</button>
    </>
  )
}

createRoot(document.getElementById('root')).render(
  <FavoriteColor />
);

6. ステートに保持できるデータ型

useState フックは、ストリング(String)、ナンバー(Number)、ブーリアン(Boolean)、アレイ(Array)、オブジェクト(Object)、およびこれらを組み合わせたあらゆるデータの追跡に使用できます。

個別の値を追跡するために、複数のステートフックを作成することも可能です。

6.1 複数のステートを使用する例

import { useState } from 'react';
import { createRoot } from 'react-dom/client';

function MyCar() {
  const [brand, setBrand] = useState("フォード");
  const [model, setModel] = useState("マスタング");
  const [year, setYear] = useState("1964");
  const [color, setColor] = useState("red");

  return (
    <>
      <h1>私の {brand}</h1>
      <p>
        これは {year} 年製の {color} の {model} です。
      </p>
    </>
  )
}

createRoot(document.getElementById('root')).render(
  <MyCar />
);

あるいは、単一のステートにオブジェクトを含めることもできます。

6.2 オブジェクトを保持する単一フックの例

import { useState } from 'react';
import { createRoot } from 'react-dom/client';

function MyCar() {
  const [car, setCar] = useState({
    brand: "フォード",
    model: "マスタング",
    year: "1964",
    color: "red"
  });

  return (
    <>
      <h1>私の {car.brand}</h1>
      <p>
        これは {car.year} 年製の {car.color} の {car.model} です。
      </p>
    </>
  )
}

createRoot(document.getElementById('root')).render(
  <MyCar />
);

単一のオブジェクト car を追跡しているため、コンポーネントをレンダリングする際はそのオブジェクトを参照する必要があります(例:car.brand)。

7. ステート内のオブジェクトや配列の更新

ステートがアップデートされると、ステート全体が上書きされます。
もし、車の「色(color)」だけをアップデートしたい場合はどうすればよいでしょうか?

もし単に setCar({color: "blue"}) と呼び出すと、ステートから brandmodelyear が削除されてしまいます。
これを防ぐために、JavaScriptの スプレッドオペレーター(Spread Operator) を活用します。

7.1 スプレッドオペレーターによる更新例

スプレッドオペレーターを使用して、車の色だけをアップデートします:

const updateColor = () => {
  setCar(previousState => {
    // 以前のステートをコピーし、colorプロパティだけを上書きする
    return { ...previousState, color: "blue" }
  });
}

現在のステートの値が必要なため、setCar 関数にコールバック関数(Function)を渡します。この関数は引数として直前の値(previousState)を受け取ります。
そして、previousState をスプレッド(展開)し、color だけを上書きした新しいオブジェクトを返します。