コース一覧
React設計:useEffectとコンポーネント分割
メモウィジェットReact版

React設計:useEffectとコンポーネント分割

副作用、useEffect、依存配列、クリーンアップ、stateの持ち上げ、propsの受け渡し、1コンポーネント1責務、部品ツリーとフォルダ構成を扱う全19レッスンの設計コースです。JavaScript版プロフィールサイトを、状態と責務が整理されたReactアプリとして完成させます。

1
useEffectのきほん
01. 副作用とは10分
02. useEffect15分
03. 依存配列15分
04. タイトル連動15分
05. 時計とクリーンアップ15分
06. つくる - ヘッダー時計20分
07. 第7章クイズ15分
2
コンポーネント分割の設計
01. 部品ツリーで考える10分
02. stateを持ち上げる15分
03. propsのバケツリレー15分
04. 1部品1責務15分
05. フォルダ構成10分
06. つくる - ツリー整理20分
07. 第8章クイズ15分
3
総合制作
01. 全セクションReact化20分
02. メモウィジェットReact版20分
03. 命令的vs宣言的10分
04. 自由拡張20分
05. 完成と次のステップ10分

メモウィジェットReact版

ここまでの全部が合流する

メモウィジェットは、JavaScript 入門の総決算として作ったものです。入力して追加し、一覧に並べ、いらなくなったら消します。React で作り直すと、state とリストとフォームという3つの話が1か所で合流します。

命令的に書いていたときは、追加のたびに createElement で li を作り、削除のたびに remove を呼んでいました。React では画面を直接いじりません。データを変えて、画面はデータから描くだけです。

state は2つに分ける

必要な state は次の2つです。

  • 入力欄の今の文字(text)
  • 追加されたメモの配列(memos)

この2つを1つにまとめたくなりますが、分けたほうが素直です。入力欄は文字を打つたびに変わり、メモの配列は追加と削除のときだけ変わります。変わるきっかけが違うものは、別の state にします。

JavaScript (JSX)

const [text, setText] = useState(""); const [memos, setMemos] = useState([]);

追加は「新しい配列を作る」

push は使いません。元の配列を書き換えても React は変化に気づかず、画面が更新されないからです。第4章でやったスプレッドで、新しい配列を作って渡します。

JavaScript (JSX)

function handleSubmit(e) { e.preventDefault(); const trimmed = text.trim(); if (trimmed === "") return; setMemos([...memos, { id: Date.now(), text: trimmed }]); setText(""); }

追加のあとに setText("") を呼んでいるのが大事なところです。入力欄の中身も state なので、空文字にすれば画面の入力欄も空になります。自分で input.value = "" と書く必要はありません。

削除は filter

削除は「その id 以外を残した新しい配列」を作ります。

JavaScript (JSX)

function handleDelete(id) { setMemos(memos.filter((memo) => memo.id !== id)); }

0件のときの画面も用意する

メモが1件も無いときに空の ul だけが残ると、壊れているように見えます。memos.length === 0 で出し分けます。

つまずきどころ

削除ボタンの onClick に onClick={handleDelete(memo.id)} と書くと、描画した瞬間に全部消えます。これは関数を呼んだ結果を渡しているからです。onClick={() => handleDelete(memo.id)} のように、押されたときに動く関数のほうを渡します。

もう1つは key です。メモの文字を key にすると、同じ文字のメモを2つ作ったときに壊れます。追加した時刻から作った id のように、重複しない値を使います。

演習

メモの追加、一覧表示、削除、0件表示までを揃えたメモウィジェットを完成させます。

ヒント

追加は setMemos([...memos, 新しいメモ]) の形で、新しい配列を作って渡します

削除は filter で、押された id 以外を残した配列を作ります

0件かどうかは memos.length === 0 で判定し、三項演算子で出し分けます

App.jsx
MemoWidget.jsx
プレビュー

できているか

  • 最初は「まだメモがありません」と表示されている
  • 入力して追加するとメモが1件並ぶ
  • もう1件追加すると2件になる
  • 削除ボタンで消していくと0件の表示に戻る
エディタを読み込んでいます