Apps

014-React Hooks|Step1-3_useStateの使い方:オブジェクト・配列のstate更新

はじめに

React の useState フックを使うと、オブジェクトや配列の状態を簡単に管理できます。

しかし、単純な数値や文字列とは異なり、オブジェクトや配列を更新する際には少し工夫が必要です。

本記事では、useState を活用してオブジェクトや配列の状態を適切に更新する方法を学びます。

概要

本記事では、以下の内容を解説します。

  • useState を使ってオブジェクトや配列を管理する方法
  • prevState を活用してオブジェクトの特定のプロパティを更新する方法
  • setState の仕組みと注意点

実際のコードを使いながら、オブジェクトの状態を変更し、それをリアルタイムで表示するフォームを作成します。これにより、React における状態管理の基礎をしっかりと身につけることができます。

実装準備:ページ作成

まずは、useState を使用したオブジェクト・配列の状態管理を試すために、基本となる React ページを作成します。Next.jsApp Router を使用して、新しいページを作成し、そこに useState を使ったフォームを実装します。

1. 新しいページコンポーネントの作成

Next.js プロジェクトの app フォルダ内に、新しいファイル Page1_3.tsx を作成します。このファイルが、今回の useState を使ったオブジェクト・配列の状態管理を試すページになります。

2. 必要なライブラリのインポート

まず、ページで使用する ReactTypography(MUI の見出しコンポーネント)、TextField(MUI の入力フィールドコンポーネント)、useState をインポートします。

MUI参照リンク

"use client";
import * as React from 'react';
import Typography from '@mui/material/Typography';
import { TextField } from '@mui/material';
import { useState } from 'react';
import MenuItem from '@mui/material/MenuItem';
  • useState を使うために import { useState } from 'react'; を追加
  • MUI(Material-UI)の TypographyTextField を使用して、UI を作成

3. 基本的なページコンポーネントの構築

次に、ページ全体を定義する Page1_3 コンポーネントを作成します。

export default function Page1_3() {
  return (
    <div>
      <Typography>useStateの使い方をマスターする</Typography><br/>
      <div>
        <h2>オブジェクトや配列のstateの更新</h2>
      </div>
    </div>
  );
}
  • Typography を使ってページのタイトルを表示
  • <h2> 見出しを追加して、オブジェクトや配列の state の更新に関する内容を示す

4. ページの表示を確認

ここまでのコードを Next.js のプロジェクト内で保存し、npm run dev または yarn dev でローカルサーバーを起動すると、作成したページがブラウザで表示されます。

次のステップでは、useState を使ってフォームの入力値を管理し、オブジェクトの状態をリアルタイムで更新する方法を実装します。

実装:手順とコードの解説

このセクションでは、useState を使用してオブジェクトの状態を管理し、フォーム入力によってその値を更新する方法を解説します。

1. 状態の初期化

まず、useState を使って form というオブジェクト型の状態を定義します。

const [form, setForm] = useState({
  name: "Y Chair",
  productNumber: "111・111・111",
  color: "Black",
});

この form オブジェクトは、以下の3つのプロパティを持っています。

  • name: 製品名(初期値: "Y Chair"
  • productNumber: 製品番号(初期値: "111・111・111"
  • color: カラー(初期値: "Black"

このオブジェクトの値を、setForm 関数を使って更新します。

2. テキスト入力による state の更新

各入力フィールドに onChange イベントを設定し、入力値が変更されるたびに form の対応するプロパティを更新します。

(1) name の更新

<TextField 
  id="outlined-basic"
  label="Name" 
  variant="outlined" 
  onChange={(e) =>
    setForm((prevForm) => ({
      ...prevForm,
      name: e.target.value,
    }))
  }
/>
<h3>{form.name}</h3>
  • onChange イベントで、入力値を form.name に反映
  • setForm を使い、オブジェクトの一部を更新(スプレッド構文 ...prevForm を使用)
  • h3 タグで現在の name の値を表示

(2) productNumber の更新

<TextField
  id="outlined-basic"
  label="Product number"
  variant="outlined"
  onChange={(e) =>
    setForm((prevForm) => ({
      ...prevForm,
      productNumber: e.target.value,
    }))
  }
/>
<h3>{form.productNumber}</h3>
  • productNumber も同様に、入力された値で state を更新

3. セレクトボックスによる color の更新

TextFieldselect プロパティを使用し、プルダウンメニューから選択できるようにします。

<TextField
  id="outlined-select-currency"
  select
  label="Color"
  defaultValue="Black"
  onChange={(e) =>
    setForm((prevForm) => ({
      ...prevForm,
      color: e.target.value,
    }))
  }
>
  {currencies.map((option) => (
    <MenuItem key={option.value} value={option.value}>
      {option.label}
    </MenuItem>
  ))}
</TextField>
<h3>{form.color}</h3>
  • select プロパティを指定し、プルダウンメニューを作成
  • currencies 配列を map でループし、選択肢を MenuItem として表示
  • onChange イベントで color の値を更新

実装手順まとめ

この実装により、オブジェクト型の state を管理し、フォームの入力値を動的に更新できます。

スプレッド構文 ...prevForm を使うことで、既存のデータを保持しつつ、特定のプロパティのみを変更することが可能です。

最終コード

"use client";
import * as React from 'react';
import Typography from '@mui/material/Typography';
import { TextField } from '@mui/material';
import { useState } from 'react';
import MenuItem from '@mui/material/MenuItem';


export default function Page1() {
  // stateをuseStateで管理:セット関数を定義
  const [form, setForm] = useState({
    name: "Y Chair",
    productNumber: "111・111・111",
    color: "Black",
  });

  const currencies = [
    {
      value: 'Black',
      label: 'Black',
    },
    {
      value: 'White',
      label: 'White',
    },
    {
      value: 'Red',
      label: 'Red',
    },
    {
      value: 'Blue',
      label: 'Blue',
    },
  ];


  return (
    <div>
      <Typography>useStateの使い方をマスターする</Typography><br/>
      <div>
        <h2>オブジェクトや配列のstateの更新</h2>
        <TextField 
          id="outlined-basic"
          label="Name" 
          variant="outlined" 
          onChange={(e) =>
            setForm((prevForm) => ({
              ...prevForm,
              name: e.target.value,
            }))
          }
        />
        <h3>{form.name}</h3>
        <br />

        
        <TextField
          id="outlined-basic"
          label="Product number"
          variant="outlined"
          onChange={(e) =>
            setForm((prevForm) => ({
              ...prevForm,
              productNumber: e.target.value,
            }))
          }
        />
       
        <h3>{form.productNumber}</h3>
        <br />

        
        <TextField
          id="outlined-select-currency"
          select
          label="Color"
          defaultValue="Black"
          onChange={(e) =>
            setForm((prevForm) => ({
              ...prevForm,
              color: e.target.value,
            }))
          }
        >
          {currencies.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
        </TextField>
        
        <h3>{form.color}</h3>
        <br />

      </div>
    </div>
  );
}

スプレッド構文とは

スプレッド構文(...)は、オブジェクトや配列の要素を展開(展開・コピー)するための構文です。React では、useState でオブジェクトや配列の state を更新する際に頻繁に使用されます。

スプレッド構文の基本的な使い方(オブジェクトの場合)

const user = {
  name: "Alice",
  age: 25
};

const updatedUser = {
  ...user,
  age: 26
};

console.log(updatedUser); 
// { name: "Alice", age: 26 }
  • ...useruser のすべてのプロパティをコピー
  • age: 26age の値のみ変更

このように、一部の値を更新しつつ、他のプロパティを維持できます。

useState でのスプレッド構文の使い方

React で useState を使ってオブジェクトの state を更新する際、スプレッド構文を使用すると、特定のプロパティのみを変更し、他の値を保持できます。

スプレッド構文を使わないとどうなる?

setForm({
  name: e.target.value
});

このコードでは、新しいオブジェクト { name: e.target.value } に置き換わってしまい、productNumbercolor の値が消えてしまいます。

スプレッド構文を使った正しい方法

setForm((prevForm) => ({
  ...prevForm, 
  name: e.target.value
}));
  • prevForm は現在の state の値
  • ...prevForm で既存の state のデータを保持
  • name のみ新しい値に更新

この方法なら、productNumbercolor の値を保持しながら、name のみ更新できます。

配列に対するスプレッド構文の使い方

配列の state を更新する際も、スプレッド構文が有効です。

const fruits = ["apple", "banana"];

const newFruits = [...fruits, "orange"];

console.log(newFruits);
// ["apple", "banana", "orange"]
  • ...fruits で既存の配列をコピー
  • "orange" を追加

配列 state の更新

setItems((prevItems) => [...prevItems, newItem]);

既存のデータを保持しつつ、新しい要素を追加できます。

スプレッド構文まとめ

  • スプレッド構文(...)は、オブジェクトや配列の要素を展開・コピーするための構文
  • useState でオブジェクトを更新する際、スプレッド構文を使わないと、他のプロパティが失われる
  • 配列の state を更新する際にも、スプレッド構文を使うことでデータを保持しながら追加が可能

スプレッド構文を活用することで、Reactstate 更新がスムーズに行えます!

まとめ

本記事では、useState を使った オブジェクト・配列の state 更新 について解説しました。

  • オブジェクトの state 更新 では、スプレッド構文 (...prevState) を使って、既存のデータを保持しながら特定のプロパティのみ変更する方法を学びました。
  • 配列の state 更新 では、スプレッド構文を活用して新しい要素を追加する方法を紹介しました。
  • スプレッド構文を適切に使うことで、state を上書きせず データを維持しながら変更を加える ことが可能になります。

React で state を適切に管理するためには、スプレッド構文の理解が欠かせません。今回の知識を活かして、より効率的な state 管理を行いましょう!

-Apps