You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:13:09