useContext في React: حل مشكلة Prop Drilling
عندما يكبر تطبيقك، ستضطر لتمرير نفس البيانات عبر عدة مكونات. هذا يُسمّى Prop Drilling ويجعل الكود مزعجًا. الحل هو استخدام Context.
ما هو useContext في React؟
هو Hook في React يسمح لك بقراءة قيمة مشتركة من Context بدل تمريرها يدويًا عبر Props، وهذا يقلّل تكرار الكود ويحل مشكلة Prop Drilling.
التعريف البسيط: useContext = الوصول للبيانات المشتركة من أي مكوّن.
الخطوة 1: إنشاء Context في React
import { createContext } from "react";
const ThemeContext = createContext("light");
هنا أنشأنا React Context للثيم مع قيمة افتراضية "light". هذا السياق سيستخدم لمشاركة قيمة الثيم بين المكونات.
هذه القيمة الافتراضية تُستخدم فقط إذا حاولت قراءة Context
بدون أن تكون داخل Provider. لذلك الأفضل دائمًا
أن تضع Provider في أعلى الشجرة حيث تحتاجه المكونات.
الخطوة 2: استخدام Provider لمشاركة البيانات
function App() {
return (
<ThemeContext.Provider value="dark">
<Navbar />
<Page />
</ThemeContext.Provider>
);
}
أي مكوّن داخل Provider سيحصل على قيمة الثيم مباشرة،
وهذا يجعل مشاركة البيانات في React أسهل بدون تمرير Props في كل مستوى.
لاحظ أننا وضعنا Navbar و Page داخل Provider،
وبالتالي كلاهما يستطيع قراءة نفس القيمة بدون تمرير Props.
الخطوة 3: قراءة قيمة Context باستخدام useContext
import { useContext } from "react";
function Navbar() {
const theme = useContext(ThemeContext);
return <div className={theme}>Navbar</div>;
}
هنا قرأنا قيمة الثيم في React بدون تمريرها من الأب، وهذا هو الهدف الأساسي من useContext.
بمجرد تغيير قيمة Provider في الأعلى، سيتم تحديث
كل المكونات التي تستخدم useContext تلقائيًا.
مثال عملي: مشاركة بيانات المستخدم في React
const UserContext = createContext(null);
function App() {
const user = { name: "Amina", role: "Admin" };
return (
<UserContext.Provider value={user}>
<Profile />
</UserContext.Provider>
);
}
function Profile() {
const user = useContext(UserContext);
return <p>مرحباً {user.name}</p>;
}
هنا قمنا بمشاركة بيانات المستخدم بين المكونات بدون تمرير Props، وهي حالة شائعة مثل عرض اسم المستخدم، الدور، أو صلاحيات الوصول.
هذا المثال يوضح كيف يصل Profile إلى بيانات المستخدم
مباشرة، حتى لو كان هناك مكونات كثيرة بينهما في الشجرة.
بدون Context كنا سنمرر user عبر عدة مستويات.
متى لا أستخدم Context في React؟
- عندما تكون البيانات محلية لمكوّن واحد.
- عندما تتغير البيانات كثيرًا جدًا، قد يسبب إعادة رندر متكرر.
- عندما تحتاج إدارة حالة معقدة (استخدم أدوات مخصصة).
الأسئلة الشائعة — FAQ
ما هو useContext في React؟
Hook يسمح بقراءة قيم مشتركة من Context.
ما هي مشكلة Prop Drilling؟
تمرير نفس البيانات عبر طبقات متعددة من المكونات.
متى أستخدم Context؟
عند وجود بيانات مشتركة مثل الثيم أو المستخدم أو اللغة.
هل Context بديل كامل لإدارة الحالة؟
لا، هو حل بسيط للمشاركة، بينما الحالات المعقدة تحتاج أدوات أخرى.
هل useContext يسبب إعادة رندر لكل المكونات؟
أي مكوّن يستهلك القيمة سيُعاد رندر عند تغييرها.