JavaScript | 1 日 90 分 × 7 日アプリ学習:簡単 ToDo アプリ(初級編)

JavaScript
スポンサーリンク

3日目のゴールと今日のテーマ

3日目のテーマは、「配列・動的追加・再描画の“関係”をもう一段クリアにすること」です。

機能としてはまだ同じです。

追加
一覧表示
全消去

でも今日は、こういうところを意識して深掘りします。

配列を「ただの箱」ではなく「アプリの状態」として捉える。
動的追加が「配列の変化」+「再描画」のセットだと理解する。
再描画を“どこからでも安心して呼べる存在”にしておく。

新機能を増やすというより、
今ある機能の“設計の芯”を強くする回です。


2日目までの ToDo アプリを、もう一度“構造”で見る

タスクは「オブジェクトの配列」になっていた

2日目で、タスクはこうなっていました。

let todos = [
  { text: "買い物に行く" },
  { text: "勉強する" }
];
JavaScript

1件はオブジェクト。
一覧は、そのオブジェクトの配列。

ここで大事なのは、

文字列じゃなくてオブジェクトにしたことで、
あとから「情報を増やす余地」を確保できたことです。

たとえば、今後こうしたくなっても耐えられます。

{ id: 1, text: "買い物に行く", done: false }
JavaScript

今日はまだ text だけで行きますが、
「タスク1件=オブジェクト」という形を再確認しておきます。

再描画は「配列 → 画面」の変換係だった

2日目の render はこうでした。

function createTodoElement(todo) {
  const itemEl = document.createElement("div");
  itemEl.textContent = todo.text;
  return itemEl;
}

function render() {
  listEl.textContent = "";

  todos.forEach((todo) => {
    const itemEl = createTodoElement(todo);
    listEl.appendChild(itemEl);
  });
}
JavaScript

やっていることはシンプルです。

画面をいったん空にする。
todos の中身を全部読み直す。
1件ずつ DOM 要素を作って追加する。

つまり、

「配列(状態)を読む → 画面を描く」

だけを担当する関数です。
この純粋さが、今日のテーマの中心になります。


配列・動的追加・再描画の“セット”を言葉で整理する

配列:アプリの「記憶」

配列 todos は、アプリの「記憶」です。

「今、どんなタスクがあるか」
は、すべて todos の中身だけを見れば分かります。

画面の内容は、
この記憶を「映しているだけ」です。

ここ、大事なのであえて言い切ります。

「正しいのは配列。画面は結果にすぎない。」

動的追加:記憶を書き換える

タスク追加の流れはこうでした。

function handleAdd() {
  const text = inputEl.value.trim();
  if (text === "") {
    return;
  }

  const todo = { text: text };
  todos.push(todo);

  inputEl.value = "";
  render();
}
JavaScript

ここでやっていることを分解すると、

入力値を取得する。
空は弾く。
オブジェクト { text } を作る。
配列 todos に push する(ここで記憶が変わる)。
その結果を画面に反映させるために render() を呼ぶ。

「配列を変えたら、すぐ render」
このセットが、「動的追加」の本質です。

再描画:記憶をもとに画面を“洗い替え”する

render は、「配列の中身をそのまま信じて、画面を作り直す」役です。

ポイントは、

足した要素だけを個別に足すのではなく、
いったん全部消してから、全タスクを描き直しているところ。

この「洗い替え」スタイルのおかげで、

「どこか一部だけずれてバグる」ということが起きづらいです。
(中級になると部分更新も出てきますが、初級では“洗い替え”が最強。)


3日目の深掘り①:配列を書き換えるパターンを意識する

パターン1:末尾に追加する

これはすでにやっています。

todos.push(todo);
JavaScript

「あとから来たものほど下に並ぶ」という、リストっぽい動きです。

パターン2:最初に追加する(発想の紹介)

今日コードに書く必要はないですが、
パターンとして知っておくといいのがこれ。

todos.unshift(todo);
JavaScript

これだと、「新しいものが上に来る」動きになります。

ToDo に限らず、

  • 新着メッセージ一覧
  • 通知一覧

なんかは、上に新しいものが来ることが多いですよね。

「push なら末尾、unshift なら先頭」
この2つのパターンを知っていると、
配列の使い方に「選択肢」が生まれます。


3日目の深掘り②:配列を“読みやすく”扱う forEach の意味

for と forEach の比較で感覚をつかむ

同じ render を、ふたつの書き方で比べてみます。

for 版:

function render() {
  listEl.textContent = "";

  for (let i = 0; i < todos.length; i++) {
    const todo = todos[i];
    const itemEl = createTodoElement(todo);
    listEl.appendChild(itemEl);
  }
}
JavaScript

forEach 版:

function render() {
  listEl.textContent = "";

  todos.forEach((todo) => {
    const itemEl = createTodoElement(todo);
    listEl.appendChild(itemEl);
  });
}
JavaScript

どちらも意味は同じです。

でも、forEach 版の方が

「todos の中身を1件ずつ取り出して、要素を作って追加している」

という“意図”が、自然に読み取れます。

ここでのポイントは、

「配列を回すとき、forEach を使うと“配列らしい処理”として読める」

という感覚です。

JavaScript に慣れてくると、

「配列 = forEach / map / filter で扱うもの」

というイメージができてきます。
3日目では、その最初の一歩として forEach を「選んで使っている」自覚を持ってみてください。


3日目の深掘り③:render を“いつ呼んでも安全”にしておく

副作用を増やしすぎない

今の render は、とても良い状態です。

  • 配列 todos を読む
  • listEl を空にする
  • 要素たちを並べ直す

それだけです。

逆に言うと、

  • 入力欄の中身を触らない
  • todos 自体を書き換えない
  • 他の要素には触らない

という “やらないこと” もちゃんと決まっています。

これによって、

どこから render() を呼んでも、
「画面が配列に合わせて整う」だけ、という安心感が生まれます。

例えば、もし render の中で input の値までいじっていたら、

「render を呼ぶたびに入力中の内容が消える」という迷惑なことになりかねません。

「関数に“やること”と“やらないこと”の境界を作る」

これは、後々めちゃくちゃ効いてくる設計の感覚です。
3日目では特に、render をそういう“安心して呼べる関数”として意識してみてください。


小さな使い勝手の補強で「設計の一貫性」を見る

Enter キー追加と「1か所に集める」思想

2日目で、Enter キーで追加できるようにしました。

inputEl.addEventListener("keydown", handleKeyDown);

function handleKeyDown(event) {
  if (event.key === "Enter") {
    handleAdd();
  }
}
JavaScript

ここで設計として美しいのは、

「クリック追加」も「Enter追加」も、
最終的に どちらも handleAdd に流れてくる ことです。

つまり、

  • 入力のきっかけ(クリック or キー)はバラバラ
  • やること(タスク追加の本体)は1か所

“入口は増やしていいけど、本体処理は1か所にまとめる”

この発想は、配列や再描画にも通じています。

  • 状態の本体は配列 todos にまとめる
  • 画面の本体処理は render にまとめる

というのと同じリズムです。


3日目のまとめと、4日目へのつなぎ

今日やったのは「新機能」ではなく、今ある機能の理解を一段深くすることでした。

言葉で整理すると、こうなります。

配列 todos は「アプリの記憶」であり、画面はその写しに過ぎないと再確認した。
動的追加は「配列を書き換える」+「再描画する」のセットであり、この順番が大事だと意識した。
再描画 render は「配列を読むだけ」の安全な関数として設計し、“いつ呼んでも大丈夫”な状態にした。
配列を回すときに forEach を使うことで、「配列を順番に処理している」ことが自然に読める形にした。
クリックとEnterを同じ handleAdd に集めたように、「本体処理を1か所にまとめる」設計センスを育てた。

4日目以降は、ここに

1件削除(「このタスクだけ消したい」をどう配列で表現するか)
完了フラグの追加(done: true/false をどう描画に反映するか)
IDの導入(どのタスクを触っているのかをどう特定するか)

といった「ToDo アプリらしさ」を少しずつ足していきます。

最後にひとつだけ、ちゃんと聞きたい。

今日の中で、「あ、自分ちょっと分かってきたな」と感じた瞬間はどこでしたか?
配列が“ただの箱”ではなく“アプリの記憶”だと腑に落ちた瞬間か、
render が「洗い替えで気持ちよく整えてくれる関数」に見えた瞬間か。

その「分かってきた感覚」が、あなたとアプリ設計をつなぐ一番大事なところです。
そこを意識しながら、4日目の ToDo 強化に進んでいきましょう。

タイトルとURLをコピーしました