مقایسه layout و template در Next.js

app router جدید در Next.js دو قرارداد فایل جدید را برای ایجاد رابط کاربری معرفی کرده است که عبارتند از: layout و template. این‌ها به ما کمک می‌کنند تا صفحات وب خود را سازماندهی کرده، تغییرات را پیگیری کنیم و وب سایت خود را سریع‌تر اجرا نماییم.

این موضوع بسیار مهم است که بدانیم چه زمانی و چگونه باید از هر یک از آن‌ها استفاده کنیم تا برنامه‌های وبی که داریم به خوبی و کارآمد کار کنند. در این مقاله قصد داریم تا تفاوت‌های بین layout و template را به روشی آسان بررسی کنیم، با نحوه تنظیم آن‌ها آشنا شویم و بهترین موقعیت‌هایی که می‌توانیم از آن‌ها استفاده کنیم را بشناسیم.

آشنایی با layout و template

Layoutها در Next.js به‌عنوان پوسته‌های دائمی رابط کاربری عمل می‌کنند که صفحات برنامه داخل آن‌ها قرار می‌گیرند. آن‌ها به توسعه‌دهندگان اجازه می‌دهند تا ساختار مشترکی را تعریف کنند که در مسیرهای مختلف بدون رندر مجدد سالم باقی بماند. این مفهوم به ویژه برای کامپوننت‌هایی مانند headerها، footerها و sidebarها که باید در حین حرکت کاربران در برنامه ثابت باقی می‌مانند، مفید است.

Templateها هم در Next.js به‌عنوان پوسته‌های رابط کاربری عمل می‌کنند که صفحات برنامه داخل آن‌ها قرار می‌گیرند، اما با یک تفاوت کلیدی: هر بار که کاربر به صفحه‌ای جدید می‌رود، یک template به‌طور کامل remount می‌شود. این فرآیند remounting، تمامی stateها و effect‌های کامپوننت را reset می‌کند و با هر انتقال صفحه، شروعی تازه را ارائه می‌دهد.

تعریف layout و template

برای تعریف layout، در فایلی به نام layout.jsیا layout.tsxیک کامپوننت React ایجاد می‌کنیم. این کامپوننت باید شامل یک prop childrenبرای ادغام layoutهای child یا صفحه‌ها باشد.

در ادامه یک مثال از کامپوننت layout را داریم:

// app/layout.tsx

import Header from "./Header";
import Footer from "./Footer";

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <div>
      <Header />
      {children}
      <Footer />
    </div>
  );
}

یک template را می‌توانیم با export کردن یک کامپوننت React پیش‌فرض از یک فایل template.jsیا template.tsxتعریف کنیم. شبیه به layout، کامپوننت باید prop children را بپذیرد و آن را رندر کند.

در ادامه یک مثال از کامپوننت template را داریم:

// app/template.tsx

"use client";
import { useEffect } from "react";

export default function Template({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    console.log("Log page view");
  }, []);
  return <div>{children}</div>;
}

نکته‌ای که وجود دارد این است که یک مسیر واحد در Next.js می‌تواند به طور موثری هم یک layout و هم یک template را شامل شود. به این صورت که layout به عنوان یک پوسته بیرونی باشد که template را درون خود قرار می‌دهد.

remounting کامپوننت: مقایسه layout و template

یک مثال کوچک برای نشان دادن remounting کامپوننت‌ها در هنگام استفاده از layout در مقابل template در نظر می‌گیریم. کار خود را با پروژه Next.js شروع می‌کنیم که با create-next-appمقداردهی اولیه شده است.

راه‌اندازی interfaceهای احراز هویت

در پوشه appبرنامه، یک دایرکتوری با نام authایجاد می‌کنیم.

در پوشه auth، یک زیر شاخه loginبا page.tsxبرای ساخت صفحه ورود اضافه می‌کنیم:

export default function LoginPage() {
  return <h1>Login</h1>;
}

یک زیر شاخهregisterبا page.tsxنیز برای صفحه ثبت نام ایجاد می‌کنیم:

export default function RegisterPage() {
  return <h1>Register</h1>;
}

پیاده‌سازی یک layout مشترک

در دایرکتوری auth، یک فایل layout.tsxایجاد می‌کنیم که شامل یک input برای گرفتن بازخورد از کاربران و لینک‌های navigation می‌باشد:

"use client";
import Link from "next/link";
import { useState } from "react";

export default function AuthLayout({ children }) {
  const [feedback, setFeedback] = useState("");
  return (
    <div>
      <label htmlFor="feedback">Your UX Feedback</label>
      <input
        id="feedback"
        value={feedback}
        onChange={(e) => setFeedback(e.target.value)}
      />
      <nav>
        <Link href="/auth/login">Login</Link>
        <Link href="/auth/register">Register</Link>
      </nav>
      {children}
    </div>
  );
}

اگر بین مسیرهای login و register جابه‌جا شویم مشاهده می‌کنیم که state مربوط به input بازخورد، حفظ می‌شود.

انتقال به یک template

نام فایل را از layout.tsxبه template.tsxتغییر می‌دهیم. با این تغییر، همانطور که بین صفحات login و register حرکت می‌کنیم، state مربوط به input بازخورد reset می‌شود. این موضوع نشان می‌دهد که با هر تغییر مسیر، کامپوننت remount می‌شود.

انتخاب بین layout و template

هنگام توسعه یک برنامه وب Next.js، با سناریوهایی مواجه می‌شویم که باید بین استفاده از layout یا template یکی را انتخاب کنیم. در ادامه یک راهنمای کلی برای کمک به تصمیم‌گیری آگاهانه در این مورد را بررسی می‌کنیم.

انتخاب layout به دلایل زیر می‌تواند مفید باشد:

  • اطمینان از بابت ثبات. می‌توانیم از layout برای ارائه ظاهر و رفتار یکنواخت در سراسر برنامه خود استفاده کنیم. استفاده از layoutبرای المنت‌های رایج مانند header و footer ایده‌آل است.
  • حفظ کردن state. استفاده از layout به دلیل توانایی آن در حفظ state و رفتارهایی که باید در طول مسیریابی پایدار باشند، مانند وضعیت login کاربر، مفید است.
  • افزایش عملکرد. layout رندرهای مجدد را به حداقل می‌رساند و مدیریت state را ساده می‌کند که این موضوع می‌تواند در نهایت منجر به بهبود عملکرد برنامه شود.

انتخاب template به دلایل زیر می‌تواند مفید باشد:

  • Isolation. استفاده از template زمانی مفید است که کامپوننت‌ها نباید state یا رفتاری را به اشتراک بگذارند. زیرا پس از navigation مجددا re-mount شده و دوباره رندر می‌شوند.
  • انعطاف‌پذیری رفتاری. اگر هر بار که کاربر به یک کامپوننت navigate می‌کند لازم است effectهای خاصی را فعال کنیم یا state را تغییر دهیم، template این قابلیت را ارائه می‌کند. به عنوان مثال، استفاده از آن می‌تواند برای موارد زیر مناسب باشد:
    • ردیابی بازدید از صفحه با useEffect.
    • جمع‌آوری بازخورد با یک فرم مدیریت شده توسط useState که برای هر صفحه منحصر به فرد است.
  • تغییر رفتارهای پیش‌فرض. Template می‌تواند نحوه عملکرد برخی ویژگی‌ها را در فریم‌ورک ما تغییر دهد. به عنوان مثال، می‌تواند نمایش UIهای fallback را در مرزهای Suspense در طول انتقال صفحه کنترل کند، که layout نمی‌تواند این کار را انجام دهد.

به طور خلاصه، layout به‌خاطر عملکرد و مزیت‌های مدیریت state، به‌ویژه برای المنت‌های استاتیک و ثابت در سراسر صفحات، یک انتخاب پیش‌فرض است. از سوی دیگر، template برای ایجاد نمونه‌های متمایز و مستقل از state کامپوننت‌ها، مورد استفاده ما قرار می‌گیرد که در آن مقداردهی اولیه effectها و state باید در هر navigation اتفاق بیفتد.

جمع‌بندی

به طور کلی layout و template در Next.js رویکردهای متمایزی را برای ساخت UI ارائه می‌کنند:

  • layout یک فریم‌ورک UI پایدار ارائه می‌کند که رندرهای مجدد را کاهش می‌دهد و state را در سراسر navigation حفظ می‌نماید، که این موضوع برای کامپوننت‌های ثابت در سراسر سایت ایده‌آل است.
  • در مقابل، template با هر بازدید از صفحه، state را reset می‌کند و مجددا رندر می‌شود، که این موضوع برای رفتارهای متمایز و خاص صفحه مناسب می‌باشد.

در نهایت layout را برای کارایی و سازگاری، و template را برای کامپوننت‌های مجزا و مستقل از state که نیاز به state به روز در طول navigation دارند، انتخاب می‌کنیم. این انتخاب درست به نیازهای خاص هر صفحه در برنامه Next.js ما بستگی دارد و تجربه کاربری و عملکرد را متعادل می‌سازد.

دیدگاه‌ها:

فرشید انجیلی

بهمن 3, 1402  در  12:36 ب.ظ

بسیار مفید و موثر
سپاس از شما

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