4日目のゴールと今日のテーマ
4日目のテーマは「同じ機能なのに“設計が一段きれいになった ToDo アプリ”を体で感じること」です。
機能としてはまだ、追加・一覧表示・全消去だけです。
でも今日は、
配列を「ただの一覧」ではなく「タスクのコレクション」として扱う。
再描画を“アプリの中心”として位置づけなおす。
コードを「意味ごとにきれいに分けて」読みやすくする。
この3つを意識します。
新しい派手な機能より、「土台を固める日」です。
ここまでの ToDo アプリを一度“設計図”として見る
タスクの持ち方を整理しておく
2日目までのタスクの形はこうでした。
let todos = [
{ text: "買い物に行く" },
{ text: "勉強する" }
];
JavaScriptひとつひとつのタスクは { text: "…" } というオブジェクト。
それが配列 todos に並んでいる、という構造です。
ここで大事なのは「タスク1件=オブジェクト1つ」という意識です。
今は text だけですが、将来 id や done フラグを増やしたくなったら、このオブジェクトに足していけば良いだけ、という拡張性があります。
再描画の役目をもう一度確認する
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 を全部読む → 画面を作り直す」だけです。
状態を書き換えない、入力欄に触らない、他の要素もいじらない。
この“純粋さ”が今日の主役です。
4日目のテーマ①:配列を「アプリの真実」として固定する
状態の本体はどこか、をハッキリさせる
改めて整理すると、今のアプリには「状態」が二つあります。
ひとつは配列 todos。
もうひとつは画面に表示されているタスクの一覧。
ここで設計として重要なのは、
正しいのは「配列 todos」だけ。
画面はそれを映しているだけ。
というルールを守り切ることです。
例えば、タスクを追加したいときに「画面に直接要素を足す」のではなく、
配列に push する。
その後に render で画面を作り直す。
という流れを徹底する。
この“徹底”そのものが、設計としての強さになります。
追加・全消去も、配列基準で考え直す
追加はこうでした。
function handleAdd() {
const text = inputEl.value.trim();
if (text === "") {
return;
}
const todo = { text: text };
todos.push(todo);
inputEl.value = "";
render();
}
JavaScript配列に新しいタスクを追加してから render。
画面はいじっていません。
全消去はこうでした。
function handleClear() {
todos = [];
render();
}
JavaScript配列を空にしてから render。
やっぱり、画面はいじりません。
この「状態の本体を配列に集中させている」という構図を意識できていると、
この先機能を増やしてもブレにくくなります。
4日目のテーマ②:再描画を“アプリの中心”として扱う
render を「最後に必ず通す」ゲートにする
今のアプリでは、画面を変えたいときは必ず render を呼びます。
この「必ずここを通る」というゲートがあると、いくつか良いことが起こります。
まず、「画面の状態は always render の結果」である、と言い切れる。
つまり、バラバラに画面を書き換えて状態がズレる、という事故が減ります。
もうひとつは、「何かバグったときに render を見ればよい」という目印があること。
配列 todos も、render も、見れば今の状況が理解できる。
これはコードを“読む未来の自分”へのプレゼントです。
「view 層」としての render を意識する
言葉の話になりますが、今の構造はこんな分担です。
配列 todos
→ アプリの「モデル」(状態、データ)
render
→ アプリの「ビュー」(見た目)
イベントハンドラ(handleAdd / handleClear など)
→ アプリの「コントローラ」(どう状態を変えるかを決める)
いきなり MVC を完璧に理解しなくても大丈夫です。
大事なのは、
状態(配列)
見た目(render)
操作(イベントハンドラ)
が、なんとなく役割ごとに分かれてきている、という感覚です。
4日目のテーマ③:コードを“意味ごとにかたまり”として整理する
今の関数たちを役割でグループ分けしてみる
関数を意味ごとに分けると、だいたいこうなります。
見た目関連
- createTodoElement
- render
状態の変更
- handleAdd
- handleClear
入力・操作の入り口
- handleKeyDown
- クリックイベントの登録(setup の中)
このグループ分けが自分の中で見えていると、
「どこを触れば何が変わるか」がクリアになります。
例えば「表示の仕方を変えたい」ときは createTodoElement / render を見る。
追加のルール(空はダメにしたいなど)を変えたいときは handleAdd を見る。
Enter の挙動を変えたいときは handleKeyDown を見る。
コードの量はまだ少ないけれど、「役割ごとに分ける」という習慣はこの段階から育てるのが一番効きます。
setup で“アプリの入口”を1か所に
2日目の最後に、こんな setup を用意していました。
function setup() {
addButton.addEventListener("click", handleAdd);
clearButton.addEventListener("click", handleClear);
inputEl.addEventListener("keydown", handleKeyDown);
render();
}
setup();
JavaScriptここでやっていることは、「アプリが動き始めるときに必要なこと」をまとめる、です。
イベント登録。
初期描画。
この二つが、アプリの“起動処理”です。
ファイルの最後に setup(); と1行あるだけで、
「ここからアプリがスタートするんだな」がひと目で分かる。
これもまた、“未来の自分への優しさ”です。
4日目の小さな発展:見た目をちょっと変えても設計が崩れない感覚
例えば、タスクの並びを変えたくなったら
今は追加したタスクが下に増えていく形ですが、
「新しいタスクを上に表示したい」と思ったとします。
配列をこう変えてもいいし、
todos.unshift(todo);
JavaScriptrender の中で、配列を逆順に回してもいいです。
function render() {
listEl.textContent = "";
[...todos].reverse().forEach((todo) => {
const itemEl = createTodoElement(todo);
listEl.appendChild(itemEl);
});
}
JavaScriptここで見てほしいのは、
「どんな表示順にしても、“配列 → render → 画面” の構造は崩れない」
ということです。
タスクの見た目を変えたいときは createTodoElement を変える。
並べ方を変えたいときは render を変える。
追加のルールを変えたいときは handleAdd を変える。
こうやって、「触る場所が明確に分かれている」というのが設計の強さです。
4日目の全体像(あらためてコードを設計として眺める)
今のアプリの骨組みを、設計目線で眺めてみます。
const inputEl = document.getElementById("todo-input");
const addButton = document.getElementById("add-button");
const clearButton = document.getElementById("clear-button");
const listEl = document.getElementById("todo-list");
let todos = [];
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);
});
}
function handleAdd() {
const text = inputEl.value.trim();
if (text === "") {
return;
}
const todo = { text: text };
todos.push(todo);
inputEl.value = "";
render();
}
function handleClear() {
todos = [];
render();
}
function handleKeyDown(event) {
if (event.key === "Enter") {
handleAdd();
}
}
function setup() {
addButton.addEventListener("click", handleAdd);
clearButton.addEventListener("click", handleClear);
inputEl.addEventListener("keydown", handleKeyDown);
render();
}
setup();
JavaScript上から順に読むと、
要素の取得。
状態(todos)。
見た目の定義。
状態変更の処理。
入力イベントの処理。
初期化処理。
という流れになっていることが分かると思います。
これ、もう立派に「設計された簡単 ToDo アプリ」です。
4日目のまとめと、5日目へのつなぎ
今日のポイントを言葉で整理します。
配列 todos を「アプリの真実の状態」として固定し、画面は常にそれを映すだけにしていると意識できた。
追加・全消去などの操作は、必ず「配列を変える」→「render を呼ぶ」という流れに乗せている。
render を「配列を読むだけの安全な関数」として設計し、“いつ呼んでも大丈夫”な存在にした。
関数を役割ごとにグループ分けして、「どこを触れば何が変わるか」が見えるようになってきた。
setup でアプリの起動処理を1か所にまとめ、「コード全体を上から下までストーリーとして読める」形になった。
5日目以降は、この土台の上に、
1件削除(特定のタスクだけ配列から消す)
完了フラグ(done を持たせて見た目で区別する)
ID でタスクを特定する
といった、「ToDo アプリらしい機能」を少しずつ足していきます。
最後にひとつ、ちゃんと聞きたい。
今日の中で、「あ、自分これ分かってきたかも」と感じたところはどこでしたか?
配列を“真実”にして画面を結果と見なした瞬間か、
render が「配列 → 画面」の変換係だとストンときた瞬間か、
関数たちの役割がふっと見えた瞬間か。
その“分かってきた感覚”が、あなたのアプリ設計の芯になります。
それを意識したまま、5日目の ToDo 強化に進んでいきましょう。

