乐闻世界logo
搜索文章和话题

What data fetching methods are available in Next.js?

2月17日 23:32

Next.js provides multiple data fetching methods, and developers can choose the appropriate approach based on different rendering strategies and requirements. Here are the main data fetching methods in Next.js:

Pages Router Data Fetching Methods

1. getStaticProps

Fetch data at build time for static site generation (SSG).

javascript
export async function getStaticProps(context) { const data = await fetch('https://api.example.com/data').then(r => r.json()); return { props: { data }, revalidate: 60, // Optional: ISR, regenerate every 60 seconds notFound: false, // Optional: Return 404 page redirect: { destination: '/login', permanent: false }, // Optional: Redirect }; } export default function Page({ data }) { return <div>{data.content}</div>; }

Use cases:

  • Data is available at build time
  • Page content doesn't change frequently
  • Need pre-rendering for better SEO

2. getServerSideProps

Fetch data on each request for server-side rendering (SSR).

javascript
export async function getServerSideProps(context) { const { req, res, query, params } = context; // Can access request and response objects const token = req.cookies.token; const data = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}` } }).then(r => r.json()); return { props: { data }, // Doesn't support revalidate }; } export default function Page({ data }) { return <div>{data.content}</div>; }

Use cases:

  • Data is only available at request time
  • Need to access request/response objects
  • Content changes frequently

3. getStaticPaths

Used for static generation of dynamic routes, defining all possible paths.

javascript
export async function getStaticPaths() { const posts = await getAllPosts(); return { paths: posts.map(post => ({ params: { slug: post.slug } })), fallback: false, // Or 'blocking' or true }; } export async function getStaticProps({ params }) { const post = await getPostBySlug(params.slug); return { props: { post }, }; } export default function BlogPost({ post }) { return <div>{post.title}</div>; }

fallback options:

  • false: Only return pre-generated paths, other paths return 404
  • 'blocking': Server renders new paths, waits for completion before returning
  • true: Immediately return static page, generate new paths in background

App Router Data Fetching Methods

1. fetch in Server Components

Use fetch directly in server components to get data.

javascript
async function Page() { const data = await fetch('https://api.example.com/data', { cache: 'force-cache', // Or 'no-store', 'no-cache', 'default' next: { revalidate: 60, // ISR tags: ['data'] // For on-demand revalidation } }).then(r => r.json()); return <div>{data.content}</div>; }

cache options:

  • force-cache: Force use of cache (default)
  • no-store: Don't use cache
  • no-cache: Validate cache every time
  • default: Use default cache strategy

2. Using React Server Components

javascript
async function BlogList() { const posts = await fetch('https://api.example.com/posts', { next: { revalidate: 3600 } }).then(r => r.json()); return ( <div> {posts.map(post => ( <PostCard key={post.id} post={post} /> ))} </div> ); }

3. Using Suspense and Streaming

javascript
import { Suspense } from 'react'; async function SlowComponent() { const data = await fetch('https://api.example.com/slow', { next: { revalidate: 60 } }).then(r => r.json()); return <div>{data.content}</div>; } export default function Page() { return ( <div> <h1>Page Title</h1> <Suspense fallback={<div>Loading...</div>}> <SlowComponent /> </Suspense> </div> ); }

Client-Side Data Fetching

1. Using useEffect

javascript
'use client'; import { useState, useEffect } from 'react'; export default function ClientDataComponent() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { fetch('/api/data') .then(res => res.json()) .then(data => { setData(data); setLoading(false); }); }, []); if (loading) return <div>Loading...</div>; return <div>{data.content}</div>; }

2. Using SWR

javascript
'use client'; import useSWR from 'swr'; const fetcher = (url) => fetch(url).then(res => res.json()); export default function SWRComponent() { const { data, error, isLoading } = useSWR('/api/data', fetcher, { revalidateOnFocus: false, revalidateOnReconnect: false, dedupingInterval: 60000, }); if (isLoading) return <div>Loading...</div>; if (error) return <div>Error</div>; return <div>{data.content}</div>; }

3. Using React Query

javascript
'use client'; import { useQuery } from '@tanstack/react-query'; async function fetchData() { const res = await fetch('/api/data'); return res.json(); } export default function ReactQueryComponent() { const { data, error, isLoading } = useQuery({ queryKey: ['data'], queryFn: fetchData, staleTime: 60000, cacheTime: 300000, }); if (isLoading) return <div>Loading...</div>; if (error) return <div>Error</div>; return <div>{data.content}</div>; }

Data Fetching Best Practices

1. Choose the Right Method

ScenarioRecommended Method
Static content, available at build timegetStaticProps / SSG
Dynamic content, needs real-time datagetServerSideProps / SSR
Needs user interactionClient-side data fetching
SEO important, content changes infrequentlySSG + ISR
Need to access request/response objectsgetServerSideProps

2. Caching Strategies

javascript
// Long-term cache fetch('/api/data', { cache: 'force-cache', next: { revalidate: 3600 } }); // Short-term cache fetch('/api/data', { cache: 'no-store' }); // On-demand revalidation fetch('/api/data', { next: { tags: ['data'] } }); // Revalidate on demand in API routes import { revalidateTag } from 'next/cache'; export async function POST() { revalidateTag('data'); return Response.json({ revalidated: true }); }

3. Error Handling

javascript
export async function getStaticProps() { try { const data = await fetchData(); return { props: { data } }; } catch (error) { return { notFound: true, }; } }

4. Loading States

javascript
// App Router - Use loading.js // app/loading.js export default function Loading() { return <div>Loading...</div>; } // Pages Router - Use custom loading component export default function LoadingPage() { return <div>Loading...</div>; }

5. Parallel Data Fetching

javascript
// Fetch multiple data sources in parallel export async function getStaticProps() { const [posts, users, comments] = await Promise.all([ fetch('/api/posts').then(r => r.json()), fetch('/api/users').then(r => r.json()), fetch('/api/comments').then(r => r.json()), ]); return { props: { posts, users, comments }, }; }

Performance Optimization Recommendations

  1. Use ISR: For content that needs regular updates, use ISR instead of SSR
  2. Cache data: Set reasonable cache times to reduce unnecessary requests
  3. Parallel fetching: Use Promise.all to fetch multiple data sources in parallel
  4. Streaming rendering: Use Suspense for streaming rendering to improve user experience
  5. Client-side caching: Use SWR or React Query to cache client-side data
  6. On-demand revalidation: Use tag system to revalidate data on demand

By properly choosing and using these data fetching methods, you can build high-performance Next.js applications with excellent user experience.

标签:Next.js