コース一覧
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

元を書き換えても React は気づかない

配列も同じ考え方

作品の一覧のように、増えたり減ったりするデータは配列の state にします。

JavaScript (JSX)

const [works, setWorks] = useState([ { id: 1, title: "レシピ検索アプリ", category: "web" }, { id: 2, title: "買い物メモツール", category: "tool" }, { id: 3, title: "写真ギャラリー", category: "web" }, ]);

オブジェクトのときと同じルールが効きます。元の配列を書きかえず、新しい配列を作って渡す のが React のやり方です。

追加する

配列に足す方法としてまず思いつくのは push です。しかし push は元の配列そのものを変えるので、React から見ると入れ物が同じままです。画面は変わりません。

JavaScript (JSX)

// 動かない works.push({ id: 4, title: "ポートフォリオサイト" });

正しくはスプレッドで新しい配列を作ります。

JavaScript (JSX)

setWorks([...works, { id: 4, title: "ポートフォリオサイト", category: "web" }]);

...works が今の要素をすべて展開し、そのうしろに新しい 1 件を並べています。先頭に足したいときは順番を入れかえて [新しい要素, ...works] と書きます。

削除する

削除には filter を使います。filter は条件に合う要素だけを集めた 新しい配列 を返すので、そのまま更新関数に渡せます。

JavaScript (JSX)

setWorks(works.filter((work) => work.id !== 3));

「id が 3 でないものだけ残す」という書き方です。splice は元の配列を変えてしまうので使いません。

書きかえる

1 件だけ内容を変えたいときは map です。条件に合う要素だけ新しいオブジェクトに差しかえ、それ以外はそのまま返します。

JavaScript (JSX)

setWorks( works.map((work) => work.id === 2 ? { ...work, title: "買い物メモ v2" } : work ) );

中でもスプレッドを使っているところに注目してください。配列も中のオブジェクトも、両方とも新しく作り直しています。

使ってよいメソッドの見分け方

迷ったら「元の配列を変えるか、新しい配列を返すか」で判断します。

  • 使える(新しい配列を返す)ものは map、filter、concat、slice、スプレッド
  • 使えない(元を変える)ものは push、pop、splice、sort、reverse

sort と reverse は元を変えるので、並べかえたいときは [...works].sort(...) のようにコピーしてから呼びます。

つまずきどころ

setWorks(works) のように今の配列をそのまま渡しても、入れ物が同じなので画面は変わりません。push したあとにこれを書いて「更新したつもり」になる事故がよくあります。更新関数に渡すのは必ず新しく作った配列です。

演習

作品の追加と削除を、元の配列を変えずに実装します。

ヒント

追加は setWorks([...works, newWork]) の形です

削除は setWorks(works.filter((work) => work.id !== 3)) の形です

App.jsx
プレビュー

できているか

  • はじめは「作品 3 件」と表示されている
  • 追加ボタンを押すと作品が 4 件になる
  • 続けて削除ボタンを押すと 写真ギャラリー が消えて 3 件になる
エディタを読み込んでいます