【Next.js】Githubのような勉強記録アプリ②:LocalStorageを活用したデータ保存

study-tracker-サムネイル Programming

前回【Next.js】Githubのような勉強記録アプリ①:簡単なTimer実装に続き、今回はLocalStorageを使って勉強内容を保存する方法を解説します。

勉強記録アプリを作る中で、「記録したデータをどのように保存するか」で悩む方も多いのではないでしょうか。特に、同じ日付のデータが重複した場合の扱いは、初心者がつまずきやすいポイントです。

この記事では、Next.jsとTypeScriptを使って、LocalStorageに勉強記録を保存する基本的な方法と、データが重複した場合の考え方について分かりやすく解説します。一見シンプルな処理に見えますが、実際に実装してみると考えることが多く、基礎の理解の大切さを改めて感じました。

この記事でわかること
  • LocalStorageの基本的な使い方(保存・取得・削除)
  • 配列やオブジェクトを扱う際のJSON変換

それでは、実装を見ていきましょう。

LocalStorageの構成

まずは、簡単にLocalStorageの構成や使い方についてまとめてみました。

特徴

・データは約5MBまで保存可能
・ブラウザから削除しない限り、基本的に半永久的に保存される
同じブラウザ内でのみデータが保持される(端末やブラウザが変わると引き継がれない)

LocalStorageは、サーバーを使わずにデータを保存できるため、簡単なアプリケーションの状態管理や、一時的なデータ保存に適しています。ただし、ブラウザごとにデータが管理されるため、ユーザーが端末を変更した場合などはデータが共有されない点には注意が必要です。

基本操作

①データの保存 (setItem)

キー(Key)とバリュー(Value)のペアで管理します。値は文字列で保存する必要があります.

// localStorage.setItem('key', 'value');
localStorage.setItem('studyTime', '120');
②データ取得(getItem)

設定したキーを使って値を取得します。

const time = localStorage.getItem('studyTime');
console.log(time); // "120"
③データ削除(removeItem / clear)

特定の値を消すことも、すべてをクリアすることも可能です。

localStorage.removeItem('studyTime'); // 特定値削除
localStorage.clear(); // すべてのデータを削除
④ 配列・オブジェクトを保存する場合 (重要!)

LocalStorageは文字列しか保存できないため、配列やオブジェクトをそのまま保存することはできません。そのため、JSON.stringifyJSON.parse を使って変換する必要があります。

保存する場合:

配列やオブジェクトは JSON.stringify を使って文字列に変換してから保存します。

const data = [{ title: "React勉強", duration: 120 }];

localStorage.setItem("studyData", JSON.stringify(data));
取得する場合:

取得したデータは文字列のため、JSON.parse を使って元の配列に戻します。

const stored = localStorage.getItem("studyData"); // データがあるか確認
const data = stored ? JSON.parse(stored) : []; // あれば変換、なければ空配列

console.log(data);

localStorage.getItem は、データが存在しない場合 null を返します。そのため、null のまま処理するとエラーになる可能性があるため、三項演算子で分岐しています。

  • データがある場合 → JSON.parse で配列に変換
  • データがない場合 → 空の配列を初期値として設定

このようにすることで、安全にデータを扱うことができます。

よくあるミス

JSON.stringify を忘れて保存してしまう
JSON.parse をしないまま使おうとしてエラーになる
null のまま処理してしまう

特に初心者の方はこの部分でつまずきやすいため、注意が必要です。

実装例(勉強記録アプリケーション)

LocalStorageを使って、実際に勉強記録アプリにデータ保存機能を実装しました。本来であればデータベースを使用した方が安定した管理が可能ですが、今回はシンプルな実装を目的としているため、LocalStorageを利用しています。

処理の流れ

今回の実装は、以下の流れでデータを保存しています。

・今日の日付を取得(キーとして使用)
・既存データを取得
・同じ日付があれば配列に追加
・なければ新しく配列を作成
・LocalStorageに保存

データ構造

{
  "2026-04-28": [studyRecord, studyRecord],
  "2026-04-27": [studyRecord]
}

日付をキーとして、その日の記録を配列で管理しています。

実装コード

// 今日の日付を取得
const now = new Date(); 
const today = `${now.getFullYear()}-${String(now.getMonth()+1).padStart(2,"0")}-${String(now.getDate()).padStart(2,"0")}`;

// 既存データを取得
const stored = localStorage.getItem("studyData");
const data: StudyData = stored ? JSON.parse(stored) : {};

// 日付ごとに処理
if (data[today]) {
  data[today].push(studyRecord); // 既にある場合は追加
} else {
  data[today] = [studyRecord]; // なければ新しく作成
}

// LocalStorageに保存
localStorage.setItem("studyData", JSON.stringify(data));

ポイント

日付をキーとして管理することで、データを整理しやすくなる
配列を使うことで、1日に複数の記録を保存できる
・LocalStorageは文字列のみ保存できるため、JSON変換が必要

このように、シンプルな構造でも基本を押さえることで、実用的なデータ管理が可能になります。

終わりに

シンプルな実装ですが、「キーを何にするか」「どう整理するか」を考える過程で、データ設計の奥深さを感じました。ただ保存するだけでなく、後から取り出しやすい形を作ることが重要ですね。

次回は、今回保存したデータを使って、GitHubのコントリビューションのような「勉強記録の可視化(芝生)」の実装に挑戦します!

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