From 0e3a70a454e422f945488d29506543a45cf0e80f Mon Sep 17 00:00:00 2001 From: Rock3r Date: Mon, 27 Apr 2026 14:50:06 +0200 Subject: [PATCH] fix(task): replace Date.now with nanoid for unique keys and update task interface --- package.json | 1 + src/App.tsx | 2 +- src/components/TaskItem.tsx | 4 ++-- src/hooks/useTasks.tsx | 19 +++++++++---------- src/types/task.ts | 2 +- yarn.lock | 5 +++++ 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 5664f2e..60f7920 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "nanoid": "^5.1.9", "react": "^19.2.5", "react-dom": "^19.2.5" }, diff --git a/src/App.tsx b/src/App.tsx index b07e132..de71656 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,7 +22,7 @@ function App() { value={inputValue} onChange={(e) => setInputValue(e.target.value)} /> - +
{tasks.length === 0 ? ( diff --git a/src/components/TaskItem.tsx b/src/components/TaskItem.tsx index 5c02d25..977908b 100644 --- a/src/components/TaskItem.tsx +++ b/src/components/TaskItem.tsx @@ -3,8 +3,8 @@ import type { Task } from "../types/task"; interface TaskItemProps { task: Task; - onDelete: (id: number) => void; - onToggle: (id: number) => void; + onDelete: (id: string) => void; + onToggle: (id: string) => void; } export const TaskItem = memo(({ task, onDelete, onToggle }: TaskItemProps) => { diff --git a/src/hooks/useTasks.tsx b/src/hooks/useTasks.tsx index 3f90afe..19fdb3f 100644 --- a/src/hooks/useTasks.tsx +++ b/src/hooks/useTasks.tsx @@ -1,5 +1,6 @@ import { useCallback, useEffect, useState } from "react"; import type { Task } from "../types/task"; +import { nanoid } from "nanoid"; export const useTasks = () => { const [tasks, setTasks] = useState(() => { @@ -15,26 +16,24 @@ export const useTasks = () => { if (title.trim() === '') return; const newTask: Task = { - id: Date.now(), - title: title, + id: nanoid(), + title, completed: false, createdAt: new Date().toISOString() }; - - setTasks([...tasks, newTask]); - + setTasks(prev => [...prev, newTask]); }; - const deleteTask = useCallback((id: number) => { - setTasks(tasks.filter(task => task.id !== id)); + const deleteTask = useCallback((id: string) => { + setTasks(prev => prev.filter(task => task.id !== id)); }, []); - const toggleTask = useCallback((id: number) => { - setTasks(tasks.map(task => + const toggleTask = useCallback((id: string) => { + setTasks(prev => prev.map(task => task.id === id ? { ...task, completed: !task.completed } : task )); }, []); - + return { tasks, addTask, deleteTask, toggleTask }; }; \ No newline at end of file diff --git a/src/types/task.ts b/src/types/task.ts index 50907c7..e31dd56 100644 --- a/src/types/task.ts +++ b/src/types/task.ts @@ -1,5 +1,5 @@ export interface Task { - id: number; + id: string; title: string; completed: boolean; createdAt: string; diff --git a/yarn.lock b/yarn.lock index 288bf97..d6d5267 100644 --- a/yarn.lock +++ b/yarn.lock @@ -999,6 +999,11 @@ nanoid@^3.3.11: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== +nanoid@^5.1.9: + version "5.1.9" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.1.9.tgz#aac959acf7d685269fb1be7f70a90d9db0848948" + integrity sha512-ZUvP7KeBLe3OZ1ypw6dI/TzYJuvHP77IM4Ry73waSQTLn8/g8rpdjfyVAh7t1/+FjBtG4lCP42MEbDxOsRpBMw== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"