A to-do list is one of the most common applications you’ll encounter in daily life. But what if you could make it dynamic with features like advanced filtering and sorting? In this post, we’ll build a simple to-do list app with Zustand, where users can filter tasks by category and sort them by priority or due date.
Why Zustand?
Zustand is a small, fast, and simple state management tool for React. It works without needing reducers, actions, or context providers. It’s perfect for lightweight applications like our to-do list.
Step 1: Setting Up Zustand Store
Let’s start by creating the Zustand store that will manage the tasks and handle the filtering and sorting.
// todoStore.js
import create from 'zustand';
const useTodoStore = create((set) => ({
tasks: [],
filter: 'all',
sortBy: 'priority',
addTask: (task) => set((state) => ({ tasks: [...state.tasks, task] })),
toggleTask: (taskId) => set((state) => ({
tasks: state.tasks.map((task) =>
task.id === taskId ? { ...task, completed: !task.completed } : task
),
})),
setFilter: (filter) => set({ filter }),
setSortBy: (sortBy) => set({ sortBy }),
}));
export default useTodoStore;
Explanation:
- tasks: Holds the to-do list.
- filter: Allows filtering tasks (e.g., show only work tasks).
- sortBy: Specifies how tasks should be sorted (e.g., by priority or due date).
- addTask, toggleTask, setFilter, setSortBy: Actions for adding tasks, toggling completion, setting filters, and sorting tasks.
Step 2: Building the UI
Here’s a simple UI to add tasks, filter them, and sort them.
// TodoList.js
import React, { useState } from 'react';
import useTodoStore from './todoStore';
const TodoList = () => {
const { tasks, filter, sortBy, addTask, toggleTask, setFilter, setSortBy } = useTodoStore();
const [newTaskText, setNewTaskText] = useState('');
const [newTaskCategory, setNewTaskCategory] = useState('work');
const [newTaskPriority, setNewTaskPriority] = useState(1);
// Filtering and Sorting
const filteredTasks = tasks.filter((task) => filter === 'all' || task.category === filter);
const sortedTasks = filteredTasks.sort((a, b) => (sortBy === 'priority' ? b.priority - a.priority : new Date(a.dueDate) - new Date(b.dueDate)));
const handleAddTask = () => {
if (newTaskText) {
addTask({ id: Date.now(), text: newTaskText, completed: false, category: newTaskCategory, priority: newTaskPriority, dueDate: new Date() });
setNewTaskText('');
}
};
return (
<div>
<h2>My To-Do List</h2>
<input value={newTaskText} onChange={(e) => setNewTaskText(e.target.value)} placeholder="New task..." />
<select onChange={(e) => setNewTaskCategory(e.target.value)}>
<option value="work">Work</option>
<option value="personal">Personal</option>
</select>
<select onChange={(e) => setNewTaskPriority(Number(e.target.value))}>
<option value={1}>High Priority</option>
<option value={2}>Medium</option>
<option value={3}>Low Priority</option>
</select>
<button onClick={handleAddTask}>Add Task</button>
<div>
<button onClick={() => setFilter('all')}>All</button>
<button onClick={() => setFilter('work')}>Work</button>
<button onClick={() => setFilter('personal')}>Personal</button>
</div>
<div>
<button onClick={() => setSortBy('priority')}>Sort by Priority</button>
<button onClick={() => setSortBy('dueDate')}>Sort by Due Date</button>
</div>
<ul>
{sortedTasks.map((task) => (
<li key={task.id} style={{ textDecoration: task.completed ? 'line-through' : 'none' }} onClick={() => toggleTask(task.id)}>
{task.text} - {task.category} - {task.priority} - {task.dueDate.toLocaleString()}
</li>
))}
</ul>
</div>
);
};
export default TodoList;
Explanation:
- Add New Task: Users can input a new task with category and priority.
- Filter Tasks: Buttons allow users to filter by category (Work/Personal).
- Sort Tasks: Users can sort tasks by priority or due date.
- Task Completion: Clicking a task toggles its completion.
Conclusion
This to-do list app demonstrates how you can create a dynamic and user-friendly task manager using Zustand for state management. We’ve added filtering and sorting to make the list more useful and easier to navigate.
With Zustand’s minimal setup and reactivity, managing state across the app is simple and efficient. Give it a try and start building your own productivity tools!
Top comments (0)