Next.js 14: Sử dụng đúng Layouts và Templates
Trong Next.js phiên bản mới, đã giới thiệu hai quy ước tệp tin mới để xây dựng UI: layouts
và templates
. Chúng giúp bạn tổ chức các trang web của mình, theo dõi các thay đổi và làm cho trang web của bạn chạy nhanh hơn.
Việc biết khi nào và cách sử dụng từng phần này là rất quan trọng để ứng dụng web của bạn hoạt động tốt và hiệu quả. Bài viết này sẽ giải thích sự khác biệt giữa layouts
và templates
một cách dễ dàng, hướng dẫn bạn cách thiết lập chúng và gợi ý những tình huống tốt nhất để sử dụng chúng.
Hiểu về layouts và templates
Trong Next.js, layouts
hoạt động như các khung giao diện người dùng cố định, bao quanh các page của ứng dụng. Chúng cho phép các nhà phát triển xác định một cấu trúc chung mà không cần render lại khi chuyển đổi giữa các route. Điều này đặc biệt hữu ích cho các thành phần như header, footer và sidebar mà cần duy trì tính nhất quán khi người dùng điều hướng qua các trang.
Templates
trong Next.js cũng hoạt động như các khung giao diện người dùng bao quanh các trang, nhưng với một khác biệt quan trọng: mỗi khi người dùng điều hướng đến một trang mới, template
được render lại hoàn toàn. Quá trình render lại này đặt lại trạng thái và hiệu ứng của thành phần, mang lại một khởi đầu mới với mỗi chuyển đổi trang.
Xác định layouts và templates
Để xác định một layout, tạo một thành phần React trong tệp tin được đặt tên là layout.js
hoặc layout.tsx
. Thành phần này nên bao gồm một prop children
để tích hợp các layout hoặc page con.
Dưới đây là một ví dụ về thành phần layout cơ bản:
// 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>
);
}
Một template có thể được xác định bằng cách xuất một thành phần React mặc định từ tệp tin template.js
hoặc template.tsx
. Tương tự như layout, thành phần này nên chấp nhận và render prop children
.
Dưới đây là một ví dụ về thành phần template cơ bản:
// 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>;
}
Mẹo: Một route duy nhất có thể chứa cả layout và template, với layout là một khung bên ngoài bao quanh template bên trong nó.
Component remounting: layouts versus templates
Hãy xem xét một ví dụ tối giản để minh họa quá trình render lại thành phần khi sử dụng layouts và templates. Bắt đầu với một dự án Next.js được khởi tạo bằng create-next-app
.
Khởi tạo giao diện xác thực
Trong thư mục app
, tạo một thư mục auth
.
Trong thư mục auth
, thêm một thư mục con login
với tệp tin page.tsx
để xây dựng trang đăng nhập:
export default function LoginPage() {
return <h1>Login</h1>;
}
Tạo một thư mục con register
với tệp tin page.tsx
cho trang đăng ký:
export default function RegisterPage() {
return <h1>Register</h1>;
}
Thiết lập shared-layout
Trong thư mục auth
, tạo một tệp tin layout.tsx
bao quanh một ô nhập phản hồi từ người dùng và các liên kết điều hướng:
"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>
);
}
Chuyển đổi giữa các route đăng nhập và đăng ký và quan sát rằng trạng thái của ô nhập phản hồi vẫn được duy trì.
Chuyển sang template
Thay đổi tên tệp tin từ layout.tsx
thành template.tsx
. Với sự thay đổi này, khi bạn điều hướng giữa các trang đăng nhập và đăng ký, trạng thái của ô nhập phản hồi được đặt lại, cho thấy rằng thành phần được render lại với mỗi thay đổi route.
Lựa chọn giữa layouts và templates
Khi phát triển một ứng dụng web, bạn sẽ gặp các tình huống mà bạn cần quyết định giữa sử dụng layouts hoặc templates. Dưới đây là một hướng dẫn để giúp bạn đưa ra quyết định thông minh:
Chọn layouts để:
- Đảm bảo sự nhất quán. Sử dụng layouts để cung cấp một diện mạo và hành vi đồng nhất cho ứng dụng của bạn. Chúng rất lý tưởng cho các thành phần chung như header và footer.
- Duy trì trạng thái. Layouts hữu ích vì khả năng giữ trạng thái và hành vi không thay đổi trong suốt quá trình điều hướng, như trạng thái đăng nhập của người dùng.
- Tăng hiệu suất. Chúng giảm thiểu việc render lại và tối ưu quản lý trạng thái, từ đó có thể cải thiện hiệu suất.
Chọn templates khi bạn cần:
- Cô lập. Templates hữu ích khi các thành phần không nên chia sẻ trạng thái hoặc hành vi, vì chúng được render lại và tải lại khi điều hướng.
- Linh động về hành vi. Nếu bạn cần kích hoạt một số hiệu ứng hoặc thay đổi trạng thái mỗi khi người dùng điều hướng đến một thành phần, templates cung cấp khả năng này. Ví dụ, chúng phù hợp với:
- Theo dõi lượt xem trang với
useEffect
. - Thu thập phản hồi với một biểu mẫu được quản lý bằng
useState
duy nhất cho mỗi trang. - Thay đổi hành vi mặc định. Templates có thể điều chỉnh cách một số tính năng hoạt động trong framework của bạn. Ví dụ, chúng có thể kiểm soát hiển thị giao diện người dùng dự phòng trong các vùng nghỉ ngơi (Suspense Boundaries) trong quá trình chuyển trang, điều mà layouts không thể làm được.
Tóm lại, mặc định sử dụng layouts vì lợi ích về hiệu suất và quản lý trạng thái, đặc biệt là đối với các thành phần tĩnh và nhất quán trên các trang. Trong khi đó, templates là lựa chọn hàng đầu để tạo ra các phiên bản độc lập với trạng thái, nơi hiệu ứng và khởi tạo trạng thái cần xảy ra trên mỗi lần điều hướng.
Kết luận
Tóm lại, layouts và templates trong Next.js cung cấp các phương pháp xây dựng giao diện người dùng khác nhau:
- Layouts cung cấp một khung giao diện người dùng ổn định giảm số lần render lại và duy trì trạng thái qua các lần điều hướng, lý tưởng cho các thành phần có tính nhất quán trên toàn trang.
- Templates, ngược lại, đặt lại trạng thái và render lại trang với mỗi lần truy cập, phù hợp với các thành phần độc lập với trạng thái yêu cầu trạng thái mới mỗi khi điều hướng.
Hãy chọn layouts cho hiệu suất và tính nhất quán, và templates cho các thành phần cô lập, độc lập với trạng thái yêu cầu trạng thái mới trên mỗi lần điều hướng. Sự lựa chọn phù hợp phụ thuộc vào nhu cầu cụ thể của từng trang trong ứng dụng Next.js của bạn, cân nhắc trải nghiệm người dùng và hiệu suất.
All rights reserved