Các Cách Lấy Dữ Liệu Next.Js

Khi xây dựng một ứng dụng được cung cấp bởi Next.js, có thể bạn sẽ cần tìm nạp dữ liệu từ một tệp, một API nội bộ hoặc một API bên ngoài. Hơn nữa, việc xác định phương pháp tìm nạp dữ liệu nào để sử dụng trong ứng dụng Next.js có thể khó hiểu – đặc biệt là việc thực hiện một yêu cầu API bên trong components render của bạn không đơn giản như bạn có thể làm trong ứng dụng React.

Mình sẽ hướng dẫn các bạn chọn phương pháp tìm nạp dữ liệu phía máy chủ phù hợp với ứng dụng của bạn (có thể sử dụng nhiều phương pháp trong một ứng dụng). Đối với mỗi phương pháp, mình sẽ nêu rõ khi nào nó chạy, lợi ích của nó và ví dụ về thời điểm bạn có thể sử dụng phương pháp này trong ứng dụng Next.js của mình.

Các phương pháp sau đây tìm nạp dữ liệu tại thời điểm build time hoặc theo từng request trước khi dữ liệu được gửi đến client.

getStaticProps (Static Generation)

Fetch data at build time. => Lấy dữ liệu tại thời điểm build time.

Phương thức getStaticProps có thể được sử dụng bên trong một Page để lấy dữ liệu ngay thời điểm build time. Một khi ứng dụng đã được built, nó sẽ không làm mới dữ liệu cho đến khi một build khác được khởi chạy.

Cách Sử Dụng:

export async function getStaticProps(context) {
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  if (!data) {
    return {
      notFound: true,
    }
  }

  return {
    props: {}, // will be passed to the page component as props
  }
}

Lợi Ích:

  • Nó cho phép trang được tạo tĩnh và giúp thời gian tải nhanh hơn khi tìm nạp dữ liệu.
  • Nếu tất cả cá Page đều sử dụng getStaticProps (hoặc không sử dụng các phương thức lấy dữ liệu từ server) thì Next.Js có thể xuất ra HTML bằng cách sử dụng lệnh next export. Điều này thuận lợi cho việc tạo trang web tĩnh và có thể lưu trữ trên Github.
  • Dữ liệu được hiển thị trước khi đến client. Điều này rất tốt cho SEO.

Ví Dụ:

Hãy tưởng tượng bạn có một trang Blog cá nhân hiển thị các trang từ các tệp markdown tại thời điểm build time. getStaticProps có thể đọc các tệp đó và lấy data vào các page component tại thời điểm build time. Khi bạn thay đổi dữ liệu blog, bạn phải rebuild site lại để thấy sự thay đổi.

getServerSideProps (Server-side Rendering)

Fetch data on each request. => Lấy dữ liệu mỗi lần request.

Phương thức getServerSideProps lấy dữ liệu mỗi khi user gửi request lên hệ thống. Nó sẽ tìm nạp dữ liệu trước khi client có thể view được trang web (trái ngược với tải trang rồi tìm nạp dữ liệu ở client). Nếu client đưa ra các request tiếp theo, dữ liệu sẽ được tìm và nạp lại.

Cách Sử Dụng:

export async function getServerSideProps(context) {
  const res = await fetch(`https://...`)
  const data = await res.json()

  if (!data) {
    return {
      notFound: true,
    }
  }

  return {
    props: {}, // will be passed to the page component as props
  }
}

Lợi Ích

  • Dữ liệu được làm mới mỗi khi client tải trang có nghĩa là dữ liệu được cập nhật kể từ khi họ truy cập trang.
  • Dữ liệu được hiển thị trước khi đến client nên rất tốt cho SEO.

Ví Dụ:

getServerSideProps nên được sử dụng để xây dựng ứng dụng đảm bảo dữ liệu được cập nhật liên tục mà không cần phải refresh trang. Ví dụ dữ liệu chứng khoán, dữ liệu tình hình Covid,…

getInitialProps (Server-side Rendering)

Fetch data on each request. => Lấy dữ liệu mỗi lần request.

getInitialProps là cách ban đầu mà ứng dụng Next.Js tìm nạp dữ liệu phía máy chủ. kể từ Next.js 9.3, các bạn nên sử dụng phương thức đã nói ở phía trên (getServerSideProps) thay vì getInitialProps.

Cách Dùng:

function Page({ stars }) {
  return <div>Next stars: {stars}</div>
}

Page.getInitialProps = async (ctx) => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const json = await res.json()
  return { stars: json.stargazers_count }
}

export default Page

Làm Thế Nào Để Xác Định Nên Sử Dụng Phương Thức Nào?

Khi sử dụng Next.Js, mình luôn đặt mục tiêu là mỗi trang ở trạng thái tĩnh. Điều này có nghĩa là cố gáng tránh sử dụng getServerSideProps và ưu tiên getStaticProps. Tuy nhiên, nếu dữ liệu thay đổi liên tục thì phải sử dụng getServerSideProps. Mình không sử dụng getInitialProps nữa.

Một Cách Tìm Nạp Dữ Liệu Phía Client-Side

Ở phía trên mình không đề cập bất kì phương pháp tìm nạp dữ liệu phía client-side nhưng các bạn có thể sử dụng useEffect hook hoặc useSwr được phát triên bởi Vercel.

SWR là chiến lược trả dữ liệu từ bộ nhớ cache trước, sau đó tìm nạp (xác thưc lại) và cuối cùng là dữ liệu cập nhật.

Tìm hiểu thêm tại đây https://swr.vercel.app/.

import useSWR from 'swr'

function Profile() {
  const { data, error } = useSWR('/api/user', fetcher)

  if (error) return <div>failed to load</div>
  if (!data) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

Tổng Kết:

Trong bài viết này mình đã giới thiệu 3 phương thức Next.Js có thể được sử dụng để tìm nạp dữ liệu tại thời điểm build time hoặc trước mỗi request phía client. Nếu các bạn có ý kiến gì thì hãy để lại bình luận bên dưới. Cám ơn!