مشروع عملي: بناء تطبيق Todo في React خطوة بخطوة
بعد أن تعلمنا الأساسيات، حان وقت أول مشروع عملي: تطبيق قائمة مهام (Todo). هذا المشروع بسيط لكنه يحتوي على كل شيء مهم: إدخال بيانات، إدارة state، وعرض قائمة بشكل ديناميكي.
ماذا سنبني؟
- إضافة مهمة جديدة.
- وضع علامة إنجاز على المهمة.
- حذف مهمة.
- حفظ المهام محليًا (اختياري).
الخطوة 1: إنشاء هيكل المشروع
import { useState } from "react";
function App() {
const [todos, setTodos] = useState([]);
const [text, setText] = useState("");
return (
<div>
<h1>قائمة المهام</h1>
</div>
);
}
الخطوة 2: إضافة مهمة جديدة
function addTodo(e) {
e.preventDefault();
if (!text.trim()) return;
setTodos([...todos, { id: Date.now(), text, done: false }]);
setText("");
}
<form onSubmit={addTodo}>
<input
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="أضف مهمة..."
/>
<button>إضافة</button>
</form>
الخطوة 3: عرض المهام
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
الخطوة 4: تحديث الحالة (إنجاز المهمة)
function toggleTodo(id) {
setTodos(
todos.map((t) =>
t.id === id ? { ...t, done: !t.done } : t
)
);
}
<li key={todo.id}>
<input
type="checkbox"
checked={todo.done}
onChange={() => toggleTodo(todo.id)}
/>
<span className={todo.done ? "done" : ""}>{todo.text}</span>
</li>
الخطوة 5: حذف مهمة
function deleteTodo(id) {
setTodos(todos.filter((t) => t.id !== id));
}
<button onClick={() => deleteTodo(todo.id)}>حذف</button>
تنبيه: لا تستخدم index كـ key في القوائم، استخدم id ثابت.
تحسين اختياري: حفظ المهام في localStorage
import { useEffect } from "react";
useEffect(() => {
const saved = localStorage.getItem("todos");
if (saved) setTodos(JSON.parse(saved));
}, []);
useEffect(() => {
localStorage.setItem("todos", JSON.stringify(todos));
}, [todos]);
أفضل الممارسات
- قسّم المكوّنات إذا كبر التطبيق (TodoItem, TodoList).
- احفظ البيانات محليًا لتجربة أفضل.
- أضف رسالة عند عدم وجود مهام.
نصيحة: حاول إضافة فلتر للمهام (الكل / المنجزة / غير المنجزة).
الأسئلة الشائعة — FAQ
ما الهدف من مشروع Todo؟
فهم إدارة الحالة في React عبر إضافة وحذف وتحديث عناصر القائمة.
هل نستخدم useState فقط؟
نعم، هذا المشروع بسيط ويكفيه useState.
كيف أحفظ المهام بعد إعادة التحميل؟
باستخدام localStorage عبر useEffect.
هل يمكن إضافة فلترة للمهام؟
نعم، عبر state إضافية تحدد الفلتر الحالي.
هل يمكن تطوير المشروع لاحقًا؟
نعم، يمكن إضافة تواريخ، تصنيفات، أو ربطه بـ API.
التالي: في المشروع القادم سنبني متجر إلكتروني بسيط.