🗂️

Zustandで簡単にローカルストレージにタスクを保存する方法

に公開

Zustandとは?

Zustand は、とってもシンプルで軽量な 状態管理ライブラリ
ReduxやRecoilよりも圧倒的に導入が簡単で、「状態のグローバル管理」と「localStorage保存」をたった数行で実現できます。

🎯 この記事のゴール

以下のような「タスク管理アプリ」で:

  • タイトル / 説明 / ステータス を持つタスクを
  • Zustandで グローバルに管理
  • さらに ローカルストレージに永続保存

する方法を、初心者にもわかりやすく紹介します!

📦 必要なもの

npm install zustand

🧠 Zustandストアの作成

以下は Zustand でタスク一覧を管理しつつ、localStorage に保存するストアです

lib/store.ts

import { create } from "zustand";
import { persist } from "zustand/middleware";

type Task = {
  id: string;
  title: string;
  description: string;
  status: "todo" | "in-progress" | "done";
};

type TaskStore = {
  tasks: Task[];
  addTask: (task: Task) => void;
  updateTask: (task: Task) => void;
  deleteTask: (id: string) => void;
};

export const useTaskStore = create<TaskStore>()(
  persist(
    (set) => ({
      tasks: [],
      addTask: (task) =>
        set((state) => ({ tasks: [...state.tasks, task] })),
      updateTask: (updatedTask) =>
        set((state) => ({
          tasks: state.tasks.map((task) =>
            task.id === updatedTask.id ? updatedTask : task
          ),
        })),
      deleteTask: (id) =>
        set((state) => ({
          tasks: state.tasks.filter((task) => task.id !== id),
        })),
    }),
    {
      name: "task-storage", // localStorageに保存されるキー名
    }
  )
);

これだけで、状態は自動的に localStorage に保存・復元されます。超かんたん!

persistというのは状態を自動的に localStorage(や sessionStorage)に保存・復元してくれる仕組みです。

✍️ タスク追加フォームの例

今回はcomponents/CreateTaskFrom.tsxというコンポーネントを作成。

タスクを一意に識別するためにuuidを使います。
uuidは「ユニバーサル一意識別子」の略で、他と絶対に被らないユニークなIDを生成するためのライブラリです。

🔧 インストール方法

npm install uuid

または

yarn add uuid

components/CreateTaskFrom.tsx

"use client";

import { useTaskStore } from "@/lib/store";
import { useState } from "react";
import { v4 as uuidv4 } from "uuid";

export function CreateTaskForm() {
  const addTask = useTaskStore((state) => state.addTask);
  const [title, setTitle] = useState("");
  const [description, setDescription] = useState("");

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();

    const newTask = {
      id: uuidv4(),
      title,
      description,
      status: "todo",
    };

    addTask(newTask);
    setTitle("");
    setDescription("");
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <input
        type="text"
        value={title}
        onChange={(e) => setTitle(e.target.value)}
        placeholder="タイトル"
        className="border p-2 w-full"
      />
      <textarea
        value={description}
        onChange={(e) => setDescription(e.target.value)}
        placeholder="説明"
        className="border p-2 w-full"
      />
      <button type="submit" className="bg-blue-500 text-white px-4 py-2">
        タスク追加
      </button>
    </form>
  );
}

📖 保存されたデータをconsole.logで確認

以下のコードで保存したタスクを確認できます。

const tasks = useTaskStore.getState().tasks;
console.log(tasks);

💡 応用編:タスクの更新や削除も可能!

const updateTask = useTaskStore((state) => state.updateTask);
const deleteTask = useTaskStore((state) => state.deleteTask);

今回定義した useTaskStore(Zustand のカスタムストア)では、以下のようにメソッドが組み込まれているため、タスク編集フォーム や 削除ボタン も簡単に使えます。

✅ まとめ

Zustandを使えば:
・🧠 状態管理が爆速で書ける
・💾 persistでlocalStorageに保存・読み込みが自動
・🔰 初心者にも優しく、シンプルなコードで完結

ちょっとしたToDoリストや学習アプリのプロトタイプに、おすすめの選択肢です!

最後に

今回はこちらで終わりです!
是非、試してみてください。

Discussion