Context چیست و ساخت آن با createContext

در فصل سوم، با Lifting State Up آشنا شدیم؛ الگویی که در آن، برای اشتراک‌گذاری یک مقدار بین چند کامپوننت، آن مقدار را به نزدیک‌ترین والد مشترک منتقل می‌کنیم و از طریق Props به فرزندان می‌دهیم. اما همان‌جا به این محدودیت هم اشاره کردیم که وقتی این مقدار باید از میان چند لایه عمیق کامپوننت عبور کند، این روش دست‌وپاگیر می‌شود. در این فصل، به سراغ راه‌حل React برای این مشکل می‌رویم: Context.

مشکل: Prop Drilling

فرض کنید می‌خواهیم اطلاعات کاربر وارد‌شده (مثلاً نامش) را در چندین سطح مختلف از درخت کامپوننت‌ها در دسترس داشته باشیم:

function App() {
  const user = { name: "سارا" };
  return <Page user={user} />;
}

function Page({ user }) {
  return <Sidebar user={user} />;
}

function Sidebar({ user }) {
  return <UserBadge user={user} />;
}

function UserBadge({ user }) {
  return <p>{user.name}</p>;
}

در این کد، user باید از App عبور کند و از میان Page و Sidebar رد شود، در حالی که هیچ‌کدام از این دو کامپوننت واقعاً به این مقدار نیاز ندارند؛ فقط آن را به فرزند بعدی منتقل می‌کنند. به این وضعیت، Prop Drilling گفته می‌شود و در برنامه‌های بزرگ، با افزایش عمق درخت کامپوننت‌ها، به‌سرعت آزاردهنده می‌شود.

Context: یک کانال مستقیم بین والد و هر فرزند

Context راهی است برای این‌که یک مقدار، بدون عبور دستی از میان هر لایه، مستقیماً در اختیار هر کامپوننتی در زیردرخت مشخصی قرار گیرد؛ فارغ از این‌که آن کامپوننت چند سطح پایین‌تر باشد.

ساخت یک Context با createContext

قدم اول، ساخت خود Context با تابع createContext است؛ معمولاً در یک فایل جداگانه، بیرون از هر کامپوننت:

import { createContext } from "react";

const UserContext = createContext(null);

مقداری که به createContext داده می‌شود (در اینجا null)، مقدار پیش‌فرض این Context است؛ مقداری که فقط زمانی استفاده می‌شود که هیچ Provider ای (که در درس بعدی با آن آشنا می‌شویم) در سطوح بالاتر درخت کامپوننت وجود نداشته باشد.

Context به‌تنهایی هنوز کاری انجام نمی‌دهد

نکته مهم این است که فراخوانی createContext، فقط خود Context را می‌سازد؛ برای این‌که واقعاً مقداری از طریق آن در دسترس کامپوننت‌های دیگر قرار گیرد، به دو چیز دیگر نیاز داریم: یک Provider که مقدار را تعیین کند، و useContext که آن مقدار را در کامپوننت مصرف‌کننده بخواند. این دو موضوع، محور درس بعدی همین فصل هستند.

Context مناسب چه نوع داده‌ای است

Context معمولاً برای داده‌هایی مناسب است که در بخش وسیعی از برنامه، توسط کامپوننت‌های مختلف و در سطوح متفاوت مورد نیاز است؛ مانند اطلاعات کاربر وارد‌شده، تم بصری برنامه (روشن/تیره)، یا زبان انتخاب‌شده. برای داده‌ای که فقط بین یک والد و یک یا دو فرزند مستقیم رد و بدل می‌شود، Props همچنان انتخاب ساده‌تر و مناسب‌تری است.

مثال قابل اجرا

ساخت یک Context (بدون Provider هنوز)
برای دیدن پیش‌نمایش کامپوننت، روی Run بزنید.

جمع‌بندی

Context راهی برای عبور دادن یک مقدار از یک والد به هر فرزندی در زیردرخت خودش است، بدون نیاز به رد کردن دستی آن از میان هر لایه میانی؛ و راه‌حل React برای مشکل Prop Drilling است. createContext فقط خود Context را با یک مقدار پیش‌فرض می‌سازد. در درس بعدی، به Provider و useContext می‌پردازیم که مقدار واقعی را تعیین و مصرف می‌کنند.