مدیریت state با استفاده از Context در Next.js

Context یکی از ویژگی‌های React است. یک کتابخانه محبوب جاوااسکریپت برای ساخت رابط‌های کاربری، که کامپوننت‌ها را قادر می‌سازد تا داده‌ها را بدون انتقال دستی، در هر سطح از درخت کامپوننت به اشتراک بگذارند. این ویژگی به ویژه برای داده‌هایی مفید است که می‌توانند برای درختی از کامپوننت‌های React به عنوان داده سراسری در نظر گرفته شوند، مانند وضعیت احراز هویت کاربر یا تم.

از طرف دیگر، Next.js یک فریم‌ورک React است که قابلیت‌هایی مانند رندر سمت سرور و تولید وب‌سایت‌های استاتیک را ارائه می‌دهد و آن را به یک راه‌حل قوی برای توسعه وب مدرن تبدیل می‌کند.

در این مقاله قصد داریم تا فرآیند استفاده از React Context در برنامه Next.js را مورد بررسی قرار دهیم. ما در مورد استفاده از context در Client Componentها، مدیریت context در Server Component و رندر third-party context providerها در server componentها بحث خواهیم کرد.

استفاده از context در Client Componentها

در Next.js، مفهوم context به طور کامل در Client Componentها پشتیبانی می‌شود. ما می‌توانیم از تمام context APIها، مانند createContext، useContextو Providerدر Client Componentهای خود استفاده کنیم. در ادامه مثالی از استفاده از context در یک Client Component داریم:

import { createContext, useContext, useState } from 'react';

const SidebarContext = createContext();

export function Sidebar() {
  const [isOpen, setIsOpen] = useState();

  return (
    <SidebarContext.Provider value={{ isOpen }}>
      <SidebarNav />
    </SidebarContext.Provider>
  );
}

function SidebarNav() {
  let { isOpen } = useContext(SidebarContext);

  return (
    <div>
      <p>Home</p>

      {isOpen && <Subnav />}
    </div>
  );
}

در این مثال، با استفاده از createContextیک context ایجاد کرده و مقدار آن را از طریق یک Providerارائه می‌کنیم. کامپوننت SidebarNavمقدار context را با استفاده از useContextمصرف می‌کند. این مفهوم به کامپوننت‌های عمیق‌تر درخت اجازه می‌دهد تا بدون اینکه context را به طور صریح به عنوان props ارسال کنند، به مقدار آن دسترسی داشته باشند.

همچنین می‌توانیم از همان کد در یک فایل جاوااسکریپت (app/sidebar.js) استفاده کنیم:

import { createContext, useContext, useState } from 'react';

const SidebarContext = createContext();

export function Sidebar() {
  const [isOpen, setIsOpen] = useState();

  return (
    <SidebarContext.Provider value={{ isOpen }}>
      <SidebarNav />
    </SidebarContext.Provider>
  );
}

function SidebarNav() {
  let { isOpen } = useContext(SidebarContext);

  return (
    <div>
      <p>Home</p>

      {isOpen && <Subnav />}
    </div>
  );
}

باید این موضوع را به خاطر داشته باشیم که providerهای context معمولاً نزدیک به root یک برنامه برای به اشتراک گذاشتن خطاهای سراسری ارائه می‌شوند.

با این حال، ایجاد یک context در root برنامه خود در Next.js باعث ایجاد خطا در server componentها می‌شود. در ادامه مقاله این موضوع را بررسی می‌کنیم.

رندر مجدد Third-Party Context Providerها در Server Componentها

React Server Componentهای Next.js از ایجاد یا استفاده مستقیم context پشتیبانی نمی‌کنند. به این ترتیب، اگر بخواهیم یک context در یک Server Component ایجاد کنیم، منجر به ایجاد خطا می‌شود. به طور مشابه، رندر کردن یک third-party context provider که دستورالعمل "use client"را ندارد نیز باعث ایجاد خطا در Server Componentها می‌شود.

در عوض، می‌توانیم Client Component خود را ایجاد کنیم که third-party provider را پوشش می‌دهد. به عنوان مثال:

'use client';

import { ThemeProvider } from 'acme-theme';
import { AuthProvider } from 'acme-auth';

export function Providers({ children }) {
  return (
    <ThemeProvider>
      <AuthProvider>{children}</AuthProvider>
    </ThemeProvider>
  );
}

در این مثال، یک Client Component به نام Providersایجاد می‌کنیم که third-party providerها، ThemeProviderو AuthProviderرا در بر می‌گیرد. ما با استفاده از دستورالعمل "use client"این کامپوننت را به عنوان یک Client Component علامت‌گذاری می‌کنیم.

اکنون، می‌توانیم <Providers />را مستقیماً در root layout برنامه خود import کرده و رندر نماییم:

import { Providers } from './providers';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

ما در کامپوننت RootLayout، کامپوننت Providersرا import و رندر می‌کنیم که کل محتوای layout را در بر می‌گیرد. این کار به همه کامپوننت‌ها و هوک‌های کتابخانه‌های third-party اجازه می‌دهد تا همانطور که انتظار می‌رود در client componentهای ما کار کنند.

با رندر کردن providers در سطح root، تمام کامپوننت‌های برنامه ما می‌توانند context ارائه شده توسط کتابخانه‌های third-party را مورد استفاده قرار دهند.

شایان ذکر است که ما باید Providers را تا حد امکان در قسمت عمیق‌تر درخت کامپوننت ارائه دهیم. در مثال بالا، کامپوننت Providersفقط {children}را به جای کل داکیومنت <html>در بر می‌گیرد. این کار به Next.js کمک می‌کند تا قسمت‌های ثابت server componentها ما را بهینه نماید.

جمع‌بندی

در این مقاله سعی کردیم تا به درک کاملی از نحوه استفاده از React Context در برنامه Next.js دست پیدا کنیم، از جمله استفاده از context در Client Componentها و رندر third-party context providerها در Server Componentها. این ویژگی قدرتمند به ما این امکان را می‌دهد که داده‌ها را به طور موثر در بین کامپوننت‌های خود در برنامه‌های Next.js به اشتراک بگذاریم.

دیدگاه‌ها:

افزودن دیدگاه جدید