State و useState — مقدمة React
State وuseState
State هي البيانات المتغيرة داخل المكون التي تُسبب إعادة الرسم عند تغييرها.
useState Hook
import { useState } from 'react';
function Counter() {
// [القيمة, دالة التحديث] = useState(القيمة الأولية)
const [count, setCount] = useState(0);
return (
<div>
<p>العداد: {count}</p>
<button onClick={() => setCount(count + 1)}>
زيادة
</button>
</div>
);
}أنواع State
1. أرقام ونصوص
const [age, setAge] = useState(25);
const [name, setName] = useState("أحمد");
const [isActive, setIsActive] = useState(false);2. Objects
const [user, setUser] = useState({
name: "أحمد",
email: "ahmed@email.com"
});
// ❌ خطأ - لا تُعدّل مباشرة
user.name = "محمد";
setUser(user);
// ✅ صحيح - أنشئ نسخة جديدة
setUser({ ...user, name: "محمد" });
// ✅ أو باستخدام دالة
setUser(prevUser => ({
...prevUser,
name: "محمد"
}));3. Arrays
const [items, setItems] = useState([]);
// إضافة عنصر
setItems([...items, newItem]);
// حذف عنصر
setItems(items.filter(item => item.id !== idToDelete));
// تحديث عنصر
setItems(items.map(item =>
item.id === idToUpdate
? { ...item, name: newName }
: item
));أمثلة عملية
نموذج تسجيل
function SignupForm() {
const [formData, setFormData] = useState({
username: "",
email: "",
password: ""
});
const [errors, setErrors] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = async (e) => {
e.preventDefault();
setIsSubmitting(true);
try {
// إرسال البيانات
await submitForm(formData);
} catch (error) {
setErrors({ submit: error.message });
} finally {
setIsSubmitting(false);
}
};
return (
<form onSubmit={handleSubmit}>
<input
name="username"
value={formData.username}
onChange={handleChange}
placeholder="اسم المستخدم"
/>
<input
name="email"
type="email"
value={formData.email}
onChange={handleChange}
placeholder="البريد الإلكتروني"
/>
<input
name="password"
type="password"
value={formData.password}
onChange={handleChange}
placeholder="كلمة المرور"
/>
<button disabled={isSubmitting}>
{isSubmitting ? "جارٍ التسجيل..." : "تسجيل"}
</button>
</form>
);
}قائمة المهام
function TodoList() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState("");
const addTodo = () => {
if (!input.trim()) return;
setTodos([
...todos,
{
id: Date.now(),
text: input,
completed: false
}
]);
setInput("");
};
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id
? { ...todo, completed: !todo.completed }
: todo
));
};
const deleteTodo = (id) => {
setTodos(todos.filter(todo => todo.id !== id));
};
return (
<div>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && addTodo()}
placeholder="مهمة جديدة..."
/>
<button onClick={addTodo}>إضافة</button>
<ul>
{todos.map(todo => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span style={{
textDecoration: todo.completed ? "line-through" : "none"
}}>
{todo.text}
</span>
<button onClick={() => deleteTodo(todo.id)}>
حذف
</button>
</li>
))}
</ul>
</div>
);
}قواعد مهمة
1. لا تُعدّل State مباشرة - استخدم دالة التحديث
2. State غير متزامن - لا تعتمد على قيمته فوراً
3. استخدم الدالة للتحديث بناءً على القيمة السابقة
4. أنشئ State منفصلة للبيانات المختلفة
import { useState } from 'react';
function ShoppingCart() {
const [items, setItems] = useState([]);
const [total, setTotal] = useState(0);
const addItem = (product) => {
setItems([...items, { ...product, id: Date.now() }]);
setTotal(prev => prev + product.price);
};
const removeItem = (id, price) => {
setItems(items.filter(item => item.id !== id));
setTotal(prev => prev - price);
};
return (
<div className="cart">
<h2>سلة التسوق ({items.length})</h2>
{items.map(item => (
<div key={item.id} className="cart-item">
<span>{item.name}</span>
<span>{item.price} دينار</span>
<button onClick={() => removeItem(item.id, item.price)}>
✕
</button>
</div>
))}
<div className="total">
المجموع: {total} دينار
</div>
</div>
);
}اختبر فهمك