Data Fetching and Caching
Hướng dẫn này sẽ hướng dẫn bạn những điều cơ bản về việc truy xuất và lưu trữ dữ liệu trong Next.js, cung cấp các ví dụ thực tế và các biện pháp thực hành tốt nhất.
Sau đây là một ví dụ tối thiểu về việc truy xuất dữ liệu trong Next.js:
export default async function Page() {
let data = await fetch('https://api.vercel.app/blog')
let posts = await data.json()
return (
{posts.map((post) => (
- {post.title}
))}
)
}
Ví dụ này trình bày cách truy xuất dữ liệu cơ bản phía máy chủ bằng cách sử dụng API truy xuất trong Thành phần máy chủ React không đồng bộ (React Server Component).
Ví dụ làm lấy dữ liệu trên máy chủ bằng Fetch API
export default async function Page() {
let data = await fetch('https://api.vercel.app/blog')
let posts = await data.json()
return (
{posts.map((post) => (
- {post.title}
))}
)
}
Thành phần này sẽ lấy và hiển thị danh sách các bài đăng trên blog. Phản hồi từ lấy sẽ được tự động lưu vào bộ nhớ đệm.
Nếu bạn không sử dụng bất kỳ hàm động nào ở bất kỳ nơi nào khác trong tuyến đường này, nó sẽ được kết xuất trước trong quá trình xây dựng tiếp theo thành một trang tĩnh. Sau đó, dữ liệu có thể được cập nhật bằng cách sử dụng Incremental Static Regeneration.
Nếu bạn không muốn lưu trữ phản hồi từ quá trình tìm nạp, bạn có thể thực hiện như sau:
let data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })
Lấy dữ liệu trên máy chủ bằng ORM hoặc cơ sở dữ liệu
Thành phần này sẽ lấy và hiển thị danh sách các bài đăng trên blog. Phản hồi từ cơ sở dữ liệu không được lưu vào bộ nhớ đệm theo mặc định nhưng có thể được lưu vào bộ nhớ đệm với cấu hình bổ sung.
import { db, posts } from '@/lib/db'
export default async function Page() {
let allPosts = await db.select().from(posts)
return (
{allPosts.map((post) => (
- {post.title}
))}
)
}
Nếu bạn không sử dụng bất kỳ hàm động nào ở bất kỳ nơi nào khác trong tuyến đường này, nó sẽ được kết xuất trước trong quá trình xây dựng tiếp theo thành một trang tĩnh. Sau đó, dữ liệu có thể được cập nhật bằng cách sử dụng Incremental Static Regeneration.
Để ngăn trang kết xuất trước, bạn có thể thêm nội dung sau vào tệp của mình:
export const dynamic = 'force-dynamic'
Tuy nhiên, bạn thường sử dụng các hàm như cookies()
, headers()
hoặc đọc searchParams
đến từ các thuộc tính trang, điều này sẽ tự động khiến trang hiển thị động. Trong trường hợp này, bạn không cần phải sử dụng rõ ràng force-dynamic
.
Lấy dữ liệu với Client Component
Chúng tôi khuyên bạn nên thử lấy dữ liệu ở phía máy chủ trước.
Tuy nhiên, vẫn có những trường hợp mà việc lấy dữ liệu ở phía máy khách là hợp lý. Trong các trường hợp này, bạn có thể gọi thủ công fetch
trong useEffect
(không khuyến khích) hoặc dựa vào các thư viện React phổ biến trong cộng đồng (chẳng hạn như SWR hoặc React Query) để truy xuất dữ liệu từ máy khách.
'use client'
import { useState, useEffect } from 'react'
export function Posts() {
const [posts, setPosts] = useState(null)
useEffect(() => {
async function fetchPosts() {
let res = await fetch('https://api.vercel.app/blog')
let data = await res.json()
setPosts(data)
}
fetchPosts()
}, [])
if (!posts) return Loading...
return (
{posts.map((post) => (
- {post.title}
))}
)
}