コース一覧
Reactで状態・フォーム・リストを扱う
オブジェクトのstate

Reactで状態・フォーム・リストを扱う

useState、イベントハンドラ、制御されたinput、フォーム送信とバリデーション、mapによるリスト表示、key、条件レンダリング、空状態を扱う全25レッスンのコースです。入力・絞り込み・ダークモードへ反応する作品ギャラリーを作り、ユーザー操作で変化するUIの基本を身につけます。

1
state(useState)
01. なぜstateが必要か15分
02. useState15分
03. ボタンで更新15分
04. 複数のstate15分
05. オブジェクトのstate15分
06. 配列のstate15分
07. 再レンダリングの仕組み10分
08. つくる - ダークモード切替20分
09. 第4章クイズ15分
2
イベントとフォーム
01. イベントハンドラ15分
02. イベントオブジェクト15分
03. 制御されたinput15分
04. 複数の入力15分
05. フォーム送信15分
06. バリデーション15分
07. つくる - 問い合わせフォーム20分
08. 第5章クイズ15分
3
リストと条件レンダリング
01. mapでリスト描画15分
02. key15分
03. 条件レンダリング(&&)15分
04. 出し分け(三項)15分
05. 空状態15分
06. 絞り込みUI15分
07. つくる - ギャラリーReact版20分
08. 第6章クイズ15分

オブジェクトのstate

オブジェクトの state は丸ごと差し替わる

まとまった値を 1 つの state にする

プロフィールの名前と肩書きと自己紹介は、いつも一緒に扱う値です。こういうものは 1 つのオブジェクトを state にすると見通しがよくなります。

JavaScript (JSX)

const [profile, setProfile] = useState({ name: "あおい", title: "Web エンジニア", bio: "動くものを作るのが好きです。JavaScript と React を勉強中です。", });

表示するときは profile.name のようにキーで取り出します。

JavaScript (JSX)

<h1>{profile.name}</h1> <p>{profile.title}</p>

直接書きかえてはいけない

肩書きだけ変えたいとき、つい次のように書きたくなります。

JavaScript (JSX)

function promote() { profile.title = "フロントエンドエンジニア"; }

これは動きません。オブジェクトの中身は確かに変わりますが、profile という 入れ物そのものは同じまま です。React は「前と違うものが来たか」を入れ物どうしの比較で判断するので、中身だけ変えても同じものだと見なし、画面を描き直しません。第 1 章で見た「変数を書きかえても画面が変わらない」のと同じことが、オブジェクトの中でも起きます。

新しいオブジェクトを作って渡す

正しいやり方は、元のオブジェクトをコピーして、変えたいキーだけ上書きした新しいオブジェクト を作ることです。ここでスプレッド構文が効きます。

JavaScript (JSX)

function promote() { setProfile({ ...profile, title: "フロントエンドエンジニア" }); }

...profile が「今の profile の全キーをここに展開する」という意味です。そのうしろに title を書いているので、title だけあとから上書きされます。name と bio は元のまま引き継がれます。

順番が大事です。次のように書くと、展開があとに来るので上書きが打ち消されてしまいます。

JavaScript (JSX)

setProfile({ title: "フロントエンドエンジニア", ...profile });

変えたいキーは必ずスプレッドのうしろ と覚えてください。

スプレッドを忘れるとどうなるか

JavaScript (JSX)

setProfile({ title: "フロントエンドエンジニア" });

これは title しか持たない別のオブジェクトになります。画面では profile.name が undefined になり、名前が消えます。「肩書きを変えたら名前が消えた」という不具合の原因はたいていこれです。

前の値から作る形

こちらも更新関数に関数を渡す書き方が使えます。

JavaScript (JSX)

setProfile((prev) => ({ ...prev, title: "フロントエンドエンジニア" }));

アロー関数でオブジェクトをそのまま返すときは、丸かっこで包む必要があります。包まないと波かっこが関数の本体だと解釈され、何も返らなくなります。

演習

プロフィールをオブジェクトの state で持ち、肩書きと自己紹介をボタンで書きかえます。

ヒント

setProfile({ ...profile, title: "フロントエンドエンジニア" }) の形で、変えたいキーをスプレッドのうしろに書きます

profile.title に直接代入しても画面は変わりません。必ず新しいオブジェクトを渡します

App.jsx
プレビュー

できているか

  • はじめの肩書きは Web エンジニア になっている
  • 肩書きを変えるボタンを押すと title だけが変わる
  • 両方のボタンを押すと肩書きと自己紹介がどちらも新しくなる
エディタを読み込んでいます