Day 49:localStorage CRUD
Day 49では、第4フェーズ「ブラウザデータ保存」の重要なまとめとして、localStorage を使った CRUD を学びます。CRUD とは、Create、Read、Update、Delete の頭文字を取った言葉で、データ操作の基本4機能を表します。日本語では、作成、読み取り、更新、削除と考えるとわかりやすいです。これまでのDay 46からDay 48では、localStorage の基本操作、入力データの保存と再表示、JSONを使った配列やオブジェクトの保存、そしてToDoデータ保存まで学んできました。Day 49では、それらを「データ操作の4つの基本」として整理し直し、よりアプリ開発らしい視点で理解を深めていきます。
ここでとても大切なのは、今まで学んだ内容が単なるバラバラの知識ではなく、CRUDという1本の流れにまとめられることです。たとえば、ToDoアプリで新しいToDoを追加するのは Create、保存済みのToDoを表示するのは Read、完了状態を変えたり内容を編集したりするのは Update、削除ボタンで消すのは Delete にあたります。このように考えると、今まで学んだことがかなり整理しやすくなります。
初心者の方にとって、CRUDは少し難しそうな英単語に見えるかもしれません。しかし、やっていることはとても身近です。メモアプリでも、ToDoアプリでも、商品一覧でも、ほとんどのデータ管理機能はこの4つで説明できます。つまり、CRUDを理解することは、アプリの基本構造を理解することでもあります。今回は、1つ1つの操作を初心者向けにかみ砕きながら、localStorage と組み合わせてどう考えるのかを丁寧に説明していきます。
CRUDとは何か
CRUDとは、データに対して行う代表的な4つの操作のことです。具体的には次の4つです。
- Create:新しいデータを作る
- Read:保存されているデータを読む
- Update:保存されているデータを更新する
- Delete:保存されているデータを削除する
初心者の方は、CRUDを「データの一生」として考えると理解しやすいです。まず新しく作られ、次に表示され、必要に応じて内容が変わり、最後に不要になったら消されます。この流れは、単なる localStorage 学習にとどまらず、今後データベースやWebアプリを学ぶときにもずっと出てくる基本です。
なぜCRUDで考えるのか
ここはとても重要です。なぜCRUDで考えるのかというと、データ操作を整理しやすくなるからです。初心者の方は、プログラムを書いていると「追加する処理」「表示する処理」「変更する処理」「消す処理」が頭の中で混ざってしまいやすいです。しかし、CRUDの視点を持つと、それぞれの処理の役割が明確になります。
たとえばToDoアプリでは、次のように整理できます。
- Create:新しいToDoを追加する
- Read:保存されたToDo一覧を表示する
- Update:ToDoを完了状態にする、内容を修正する
- Delete:不要なToDoを削除する
このように分類できるようになると、コードを読むときも書くときも考えやすくなります。初心者の方は、機能を増やす前に「これはCRUDのどれにあたるか」を意識すると、設計の力がつきやすいです。
Day 49で扱うデータの考え方
今回も、Day 48と同じく、localStorage に保存するデータは配列とオブジェクトを使って考えるのがわかりやすいです。なぜなら、CRUDを体験するには、複数のデータをまとめて扱う必要があるからです。
たとえば、ToDoデータなら次のような形です。
const todos = [
{ text: "買い物に行く", completed: false },
{ text: "JavaScriptを勉強する", completed: true }
];JavaScriptここで大事なのは、アプリの本体はこの todos 配列だということです。画面に表示されているリストが本体ではありません。データの本体はJavaScriptの配列であり、それを localStorage に保存し、必要なときに読み出して画面に反映します。初心者の方は、この「データ本体」と「画面表示」は別だという感覚をしっかり持つことが大切です。
Create:新しいデータを作る
最初に学ぶのは Create です。Create は、新しいデータを追加する操作です。ToDoアプリなら、新しいToDoを配列に追加することがCreateにあたります。
たとえば、入力欄から受け取った内容を新しいオブジェクトとして todos 配列に追加するコードは次のようになります。
// 新しい ToDo を追加する
todos.push({
text: "部屋を片づける",
completed: false
});
これだけで配列の中に新しいToDoデータが増えます。しかし、初心者の方はここで終わりではないことに注意が必要です。配列に追加しただけでは、localStorage にはまだ反映されていませんし、画面表示も変わりません。つまりCreateでは、少なくとも次の3段階を考える必要があります。
- 配列に新しいデータを入れる
- `localStorage` に保存する
- 画面を更新する
この流れを意識することが非常に重要です。
Createの実践例
ToDoを追加し、保存し、画面に反映する流れをコードで見るとこうなります。
// 新しい ToDo を配列に追加する
todos.push({
text: inputValue,
completed: false
});
// localStorage に保存する
localStorage.setItem("todos", JSON.stringify(todos));
// 画面を更新する
renderTodos();JavaScript初心者の方は、ここで「配列操作」「保存」「表示更新」がセットになっていることを意識するとよいです。Createは単に push() を使うだけではなく、その後に保存と再表示まで含めて考える必要があります。
Read:保存されたデータを読む
次は Read です。Read は、保存されているデータを取り出して使う操作です。localStorage 学習では、ページ読み込み時に保存データを取り出して表示する処理がこれにあたります。
たとえば、ToDo一覧を取り出す処理はこう書けます。
// localStorage から保存データを取得する
const savedTodos = localStorage.getItem("todos");
// 保存データがあれば配列に戻す
const todos = savedTodos !== null ? JSON.parse(savedTodos) : [];JavaScriptこのコードでは、まず getItem() で文字列として取り出し、それを JSON.parse() で元の配列に戻しています。初心者の方は、Readを「保存されているものをアプリの中で使える形に戻す処理」と考えるとわかりやすいです。
Readの本当の役割
Readで重要なのは、ただデータを取り出すだけではなく、「取り出したデータをどう使うか」です。たとえば、取り出したToDo配列を画面に表示する処理までできて初めて、ユーザーにとって意味のあるReadになります。
// ToDo を画面に表示する関数
function renderTodos() {
// リストを空にする
todoList.innerHTML = "";
// 配列の中身を順番に表示する
for (const todo of todos) {
const li = document.createElement("li");
li.textContent = todo.text;
todoList.appendChild(li);
}
}JavaScriptつまり、Readは「読み出して終わり」ではなく、「読み出して画面や処理に使う」までが大切です。初心者の方は、保存データを見える形にするところまでセットで理解すると実践的です。
Update:既存データを更新する
次は Update です。Update は、すでにあるデータを変更する操作です。ToDoアプリでいえば、完了状態を変えることや、内容を編集することがUpdateにあたります。
まずはわかりやすい例として、完了状態の切り替えを考えます。たとえば、配列の中のあるToDoの completed を true に変えると、それは更新です。
// 1件目の ToDo を完了状態にする
todos[0].completed = true;JavaScriptこの1行だけで、配列内のデータは更新されます。しかし、Createと同じく、ここでも localStorage の保存と画面更新が必要です。つまり、Updateでも次の流れが大切です。
- 配列の中身を変更する
- `localStorage` に上書き保存する
- 画面を更新する
初心者の方は、Updateを「既存データを少し変えて、保存し直すこと」と考えるとよいです。
Updateの実践例
たとえば、クリックしたToDoの完了状態を切り替えるなら、次のような流れになります。
// completed の値を反転させる
todos[index].completed = !todos[index].completed;
// localStorage に保存し直す
localStorage.setItem("todos", JSON.stringify(todos));
// 画面を更新する
renderTodos();JavaScriptここでのポイントは、! を使って true と false を切り替えていることです。初心者の方にとっては少し慣れが必要ですが、「今が true なら false、false なら true にする」という意味です。
また、Updateは「追加ではなく変更」だという点が大切です。初心者の方は、CreateとUpdateを混同しないように意識すると理解が整理しやすいです。
Delete:不要なデータを削除する
最後は Delete です。Delete は、保存されているデータを消す操作です。ToDoアプリなら、不要なToDo項目を配列から取り除くことがDeleteです。
たとえば、配列の特定の位置にあるToDoを削除するなら splice() を使えます。
// index 番目の ToDo を1件削除する
todos.splice(index, 1);JavaScriptこれで、指定したToDoが配列から消えます。しかし、ここでも終わりではありません。やはり localStorage の保存と画面更新が必要です。
// 配列から削除する
todos.splice(index, 1);
// localStorage に保存し直す
localStorage.setItem("todos", JSON.stringify(todos));
// 画面を更新する
renderTodos();JavaScript初心者の方は、Deleteも「データ本体を消す」「保存し直す」「見た目を直す」の3段階で考えると理解しやすいです。
CRUDを1本の流れとして見る
ここまでで、Create、Read、Update、Delete の4つを個別に見てきました。ここで大切なのは、これらが別々の知識ではなく、1つのアプリの中でつながっていることです。
たとえばToDoアプリでは、次のような流れになります。
- ページが開いたら保存データを読む(Read)
- 新しいToDoを追加する(Create)
- 完了状態を切り替える(Update)
- 不要なToDoを消す(Delete)
このように、CRUDはアプリ全体の流れそのものです。初心者の方は、「これはただの追加機能」「これはただの削除機能」と個別に見るだけでなく、「アプリの中のCRUDの一部」として理解できるようになるとかなり成長できます。
実践:localStorage CRUD対応のToDoアプリ
ここでは、CRUDを一通り体験できる簡単なToDoアプリの完成版を紹介します。今回は、追加、表示、完了切り替え、削除までを含めます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Day 49 localStorage CRUD</title>
<style>
/* 完了済み ToDo の見た目 */
.completed {
text-decoration: line-through;
color: gray;
}
/* リスト項目の余白 */
li {
margin-bottom: 8px;
}
/* ボタンの余白 */
button {
margin-left: 8px;
}
</style>
</head>
<body>
<h2>localStorage CRUD ToDoアプリ</h2>
<input type="text" id="todoInput" placeholder="ToDoを入力してください">
<button id="addButton">追加</button>
<ul id="todoList"></ul>
<script>
// 必要な要素を取得する
const todoInput = document.getElementById("todoInput");
const addButton = document.getElementById("addButton");
const todoList = document.getElementById("todoList");
// localStorage から保存データを取得する
const savedTodos = localStorage.getItem("todos");
// 保存データがあれば配列に戻し、なければ空配列を使う
let todos = savedTodos !== null ? JSON.parse(savedTodos) : [];
// localStorage に保存する関数
function saveTodos() {
localStorage.setItem("todos", JSON.stringify(todos));
}
// ToDo を画面に表示する関数
function renderTodos() {
// いったん表示を空にする
todoList.innerHTML = "";
// 配列の内容を1件ずつ表示する
todos.forEach(function (todo, index) {
// li 要素を作成する
const li = document.createElement("li");
// ToDo テキストを表示する span を作る
const span = document.createElement("span");
span.textContent = todo.text;
// 完了済みならクラスを追加する
if (todo.completed) {
span.classList.add("completed");
}
// 完了ボタンを作成する
const completeButton = document.createElement("button");
completeButton.textContent = "完了切替";
// 削除ボタンを作成する
const deleteButton = document.createElement("button");
deleteButton.textContent = "削除";
// 完了ボタンの処理
completeButton.addEventListener("click", function () {
// completed を反転させる
todos[index].completed = !todos[index].completed;
// 保存し直す
saveTodos();
// 画面を更新する
renderTodos();
});
// 削除ボタンの処理
deleteButton.addEventListener("click", function () {
// 配列から削除する
todos.splice(index, 1);
// 保存し直す
saveTodos();
// 画面を更新する
renderTodos();
});
// li に要素を追加する
li.appendChild(span);
li.appendChild(completeButton);
li.appendChild(deleteButton);
// リストに追加する
todoList.appendChild(li);
});
}
// 追加ボタンの処理
addButton.addEventListener("click", function () {
// 入力内容を取得して空白を除く
const text = todoInput.value.trim();
// 空欄なら追加しない
if (text === "") {
return;
}
// 新しい ToDo を配列に追加する
todos.push({
text: text,
completed: false
});
// 保存する
saveTodos();
// 画面を更新する
renderTodos();
// 入力欄を空にする
todoInput.value = "";
});
// 初期表示
renderTodos();
</script>
</body>
</html>
このテンプレートにはCRUDの基本がすべて入っています。
- Create:追加ボタンで新しいToDoを作る
- Read:ページ読み込み時に保存データを表示する
- Update:完了状態を切り替える
- Delete:不要なToDoを削除する
この完成版コードの見方
初心者の方は、完成版コードを一気に見ると長く感じるかもしれません。そのときは、CRUDごとに分けて読むと理解しやすいです。
- Read は最初の `localStorage.getItem()` と `renderTodos()` です。
- Create は追加ボタンのイベント処理です。
- Update は完了切替ボタンのイベント処理です。
- Delete は削除ボタンのイベント処理です。
このように分解すると、「長いコード」ではなく「4つの役割が集まったコード」として見えてきます。初心者の方は、1つずつ役割を意識して読む習慣をつけると、コード読解力がかなり上がります。
特に深掘りしたい重要ポイント
Day 49で特に重要なのは、CRUDのどの操作でも結局やっていることの核は似ているということです。つまり、
- データ本体である配列を変更する
- `localStorage` に保存し直す
- 画面を再表示する
この3つが基本になります。Create、Update、Delete は、配列への触り方が違うだけで、その後の流れはよく似ています。この視点を持てると、今後もっと複雑な機能を作るときにも整理しやすくなります。
また、Readだけは少し役割が違い、「保存されているものを読み込み、アプリの起点を作る」処理です。初心者の方は、この違いを意識しておくとよいです。
初心者が特に注意したいポイント
Day 49では、次の点を特に意識すると理解が深まりやすいです。
- 配列がデータ本体であり、画面はその結果として作られています。
- Create、Update、Delete のあとは `localStorage` に保存し直す必要があります。
- 保存し直したあとに画面も更新しないと、見た目とデータがずれることがあります。
- Readでは、保存データがない場合を考えて空配列を使うのが安全です。
- CRUDはToDoアプリだけでなく、ほとんどのデータ管理アプリに共通する考え方です。
特に大切なのは、「データ本体を変えること」と「画面を変えること」は別だという点です。初心者の方は、画面だけ変わって安心してしまいがちですが、本当に重要なのは配列データと localStorage が正しく更新されていることです。
情報セキュリティの観点での注意
localStorage を使ったCRUDは学習や簡易アプリにはとても便利ですが、保存するデータの種類には引き続き注意が必要です。ToDoやメモ、表示設定などには向いていますが、パスワードや機密性の高い個人情報を保存するのには適していません。
初心者の方は、便利だから何でも保存するのではなく、「これはブラウザ内に保存してよい情報か」と一度考える習慣をつけると、安全なプログラミングに近づきます。
Day 49のゴールを整理する
Day 49では、次のことができるようになっていれば十分です。
- CRUDの意味を説明できる
- Create、Read、Update、Delete をToDoアプリで対応づけて説明できる
- `localStorage` と JSON を使って配列データを保存できる
- 保存データを読み込んで画面に表示できる
- 既存データの更新ができる
- 不要なデータの削除ができる
- データ本体、保存、画面更新の関係を説明できる
ここまでできれば、Day 49としてはとても順調です。ブラウザデータ保存の基礎が、アプリ開発の基本概念であるCRUDとしっかり結びついています。
まとめ
Day 49では、第4フェーズ「ブラウザデータ保存」のまとめとして、localStorage を使ったCRUDを学びました。CRUDとは、Create、Read、Update、Delete の4つの基本操作であり、データを扱うアプリの土台になる考え方です。ToDoアプリを例にすると、新しいToDoを追加するのがCreate、保存されたToDoを表示するのがRead、完了状態や内容を変更するのがUpdate、不要なToDoを消すのがDeleteにあたります。
今回特に重要だったのは、画面に見えているものが本体ではなく、JavaScriptの配列データが本体であり、そのデータを localStorage に保存し、必要に応じて読み出し、画面に反映しているという考え方です。そしてCreate、Update、Deleteのあとには、配列を変更するだけでなく、保存し直して画面も更新する必要があります。この流れを理解できると、ただコードを写すだけではなく、「なぜこの処理が必要なのか」を自分で説明できるようになります。
次に進む前に、今回の完成版テンプレートを何も見ずにもう一度作り直してみるのがおすすめです。そのうえで、完了済みだけを表示する機能や、ToDo内容を編集する機能を追加してみると、CRUDの理解がさらに深まりやすくなります。
