跳转到内容

Next.js fetch API

来自代码酷
Admin留言 | 贡献2025年5月1日 (四) 23:15的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

Next.js fetch API[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

Next.js fetch API 是 Next.js 框架中用于数据获取的核心工具,它基于原生的 JavaScript fetch API,并进行了扩展以支持服务端渲染(SSR)、静态生成(SSG)和增量静态再生(ISR)等特性。fetch API 允许开发者在客户端或服务器端发起 HTTP 请求,获取远程数据并渲染页面内容。

Next.js 对 fetch API 的增强包括:

  • 自动去重重复请求
  • 内置缓存机制
  • 支持动态数据获取(如重新验证)
  • 与 React 服务器组件(RSC)深度集成

基本用法[编辑 | 编辑源代码]

以下是 Next.js fetch API 的基本语法:

async function getData() {
  const res = await fetch('https://api.example.com/data')
  // 默认会缓存结果
  return res.json()
}

export default async function Page() {
  const data = await getData()
  
  return <div>{data.title}</div>
}

输入与输出示例[编辑 | 编辑源代码]

假设 API 端点返回以下 JSON:

{
  "title": "Next.js Fetch API Guide",
  "author": "Next.js Team"
}

页面将渲染为:

<div>Next.js Fetch API Guide</div>

缓存行为[编辑 | 编辑源代码]

Next.js fetch API 默认会缓存响应结果。缓存行为可以通过选项控制:

graph LR A[fetch请求] --> B{有缓存?} B -->|是| C[返回缓存] B -->|否| D[发起网络请求] D --> E[存储响应到缓存]

缓存控制选项[编辑 | 编辑源代码]

// 不缓存
fetch('https://api.example.com/data', { cache: 'no-store' })

// 每10秒重新验证
fetch('https://api.example.com/data', { next: { revalidate: 10 } })

数据获取策略[编辑 | 编辑源代码]

Next.js 支持多种数据获取策略:

静态生成 (SSG)[编辑 | 编辑源代码]

// 在构建时获取数据
export async function getStaticProps() {
  const res = await fetch('https://api.example.com/static-data')
  const data = await res.json()
  
  return {
    props: { data }
  }
}

服务器端渲染 (SSR)[编辑 | 编辑源代码]

// 每次请求时获取数据
export async function getServerSideProps() {
  const res = await fetch('https://api.example.com/dynamic-data', { 
    cache: 'no-store' 
  })
  const data = await res.json()
  
  return {
    props: { data }
  }
}

增量静态再生 (ISR)[编辑 | 编辑源代码]

// 静态生成但定期更新
export async function getStaticProps() {
  const res = await fetch('https://api.example.com/isr-data')
  const data = await res.json()
  
  return {
    props: { data },
    // 每60秒重新生成页面
    revalidate: 60 
  }
}

高级用法[编辑 | 编辑源代码]

请求去重[编辑 | 编辑源代码]

Next.js 会自动去重同时发起的相同请求: Runique=i=1nRiwhereRiRjforij

错误处理[编辑 | 编辑源代码]

async function getData() {
  try {
    const res = await fetch('https://api.example.com/data')
    if (!res.ok) {
      throw new Error('Failed to fetch data')
    }
    return res.json()
  } catch (error) {
    console.error('Error:', error)
    return null
  }
}

自定义请求[编辑 | 编辑源代码]

fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ key: 'value' }),
})

实际应用案例[编辑 | 编辑源代码]

电商产品页面[编辑 | 编辑源代码]

export async function generateStaticParams() {
  const res = await fetch('https://api.example.com/products')
  const products = await res.json()
  
  return products.map((product) => ({
    id: product.id.toString(),
  }))
}

export default async function ProductPage({ params }) {
  const res = await fetch(`https://api.example.com/products/${params.id}`)
  const product = await res.json()
  
  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <p>Price: ${product.price}</p>
    </div>
  )
}

实时仪表盘[编辑 | 编辑源代码]

export const dynamic = 'force-dynamic' // 禁用所有缓存

export default async function Dashboard() {
  const res = await fetch('https://api.example.com/metrics', { 
    cache: 'no-store' 
  })
  const metrics = await res.json()
  
  return (
    <div>
      <h2>实时指标</h2>
      <ul>
        {metrics.map((metric) => (
          <li key={metric.id}>{metric.name}: {metric.value}</li>
        ))}
      </ul>
    </div>
  )
}

最佳实践[编辑 | 编辑源代码]

1. 对于不常变化的数据,使用静态生成或ISR 2. 对于敏感数据,使用服务器端获取 3. 合理设置重新验证时间 4. 始终处理错误情况 5. 使用TypeScript增强类型安全

TypeScript示例[编辑 | 编辑源代码]

interface Product {
  id: number
  name: string
  price: number
  description: string
}

async function getProduct(id: number): Promise<Product> {
  const res = await fetch(`https://api.example.com/products/${id}`)
  return res.json()
}

性能考虑[编辑 | 编辑源代码]

  • 批量请求减少网络往返
  • 使用流式传输处理大响应
  • 考虑CDN缓存策略
  • 监控API响应时间

常见问题[编辑 | 编辑源代码]

为什么我的fetch请求没有被缓存?[编辑 | 编辑源代码]

检查是否设置了cache: 'no-store'选项或在动态渲染的页面中使用了fetch。

如何在客户端组件中使用fetch?[编辑 | 编辑源代码]

在客户端组件中,可以直接使用原生fetch API,但建议通过API路由中转敏感请求。

fetch与第三方库(如axios)比较[编辑 | 编辑源代码]

Next.js fetch API的优势在于深度框架集成和自动优化,而axios等库提供更多高级功能和浏览器兼容性。