Next.js 13 + TypeScript:API响应数据映射实现问题求助
Next.js 13.4 数据获取问题解决指南
我刚学Next.js没几天,搞不懂怎么在13.4版本里从API获取数据。之前用普通React的时候,都是用useState和useEffect来处理数据请求,但Next.js 13.4里该怎么做?
我的代码如下:
import { ProductType } from '../Types/productTypes'; import Image from 'next/image'; async function getData() { const res = await fetch('https://dummyjson.com/products'); if (!res.ok) { throw new Error('Failed to fetch data'); } return res.json(); } export default async function ProductPage() { const data: ProductType[] = await getData() return ( <main> {data.map((product) => ( <div key={product.id} className='border p-4'> <h3 className='text-xl font-semibold'>{product.title}</h3> <p className='text-gray-500'>${product.price}</p> <Image src={product.thumbnail} alt={product.title} className='mt-4 mb-2 w-full h-48 object-contain' /> <button className='bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded'>More details</button> </div> ))} </main> ); }
类型定义:
export type ProductType = { id: number; title: string; description: string; price: number; discountPercentage: number; rating: number; stock: number; brand: string; category: string; thumbnail: string; images: string[]; };
问题分析与修正
你的核心思路是对的:Next.js 13.4 App Router支持服务器组件直接异步获取数据,不需要依赖useState/useEffect。但代码存在一个数据结构不匹配的问题:https://dummyjson.com/products返回的是包含products数组的对象(格式如下),而非直接的ProductType[]数组:
{ "products": [/* 产品列表 */], "total": 100, "skip": 0, "limit": 30 }
修正方案1:调整getData函数返回值
async function getData() { const res = await fetch('https://dummyjson.com/products'); if (!res.ok) { throw new Error('Failed to fetch data'); } // 解构出products数组后返回 const { products } = await res.json(); return products; } export default async function ProductPage() { const data: ProductType[] = await getData() return ( <main className="grid grid-cols-1 md:grid-cols-3 gap-4 p-4"> {data.map((product) => ( <div key={product.id} className='border p-4'> <h3 className='text-xl font-semibold'>{product.title}</h3> <p className='text-gray-500'>${product.price}</p> {/* Next.js Image需配合容器使用fill属性,或指定width/height */} <div className="relative w-full h-48 mt-4 mb-2"> <Image src={product.thumbnail} alt={product.title} fill className='object-contain' /> </div> <button className='bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded'>More details</button> </div> ))} </main> ); }
修正方案2:在组件内解构数据
export default async function ProductPage() { // 先获取完整响应,再解构出products数组 const response = await getData(); const data: ProductType[] = response.products; return ( // 同上述JSX内容 ); }
Next.js 13.4 数据获取关键要点
- 默认情况下App Router的组件是服务器组件,支持直接用
async/await在服务器端预取数据,无需客户端钩子,性能更优。 - 如果需要在客户端组件中触发数据请求(比如交互触发),可以沿用普通React的
useState+useEffect,或使用SWR/React Query这类数据请求库。 - Next.js的
fetch默认自带缓存,可通过cache: 'no-store'或revalidate参数控制缓存策略。
内容的提问来源于stack exchange,提问作者antonkornilov-ua
相关产品推荐
相关产品推荐

