Next.js组件getServerSideProps获取API数据异常:数据为空或undefined排查
问题:Next.js getServerSideProps 获取数据为空/undefined,无法展示UI
我尝试通过getServerSideProps从jsonplaceholder获取数据,但始终得到undefined或空数组,无法在UI中展示数据。以下是完整组件代码:
import { GetServerSideProps, NextPage } from 'next'; import Image from 'next/image'; import React from 'react'; import photo from '../../assets/photo.jpg'; type Products = { data?: { id: number; title: string; body: string; }[]; }; const defaultProducts: Products = { data: [], }; const ExploreProducts: NextPage<Products> = ({ data = defaultProducts.data }) => { console.log(data); return ( <div> <div className='grid grid-cols-12 gap-5'> {data?.map(product => ( <div className="card w-96 bg-base-100 shadow-xl" key={product.id}> <figure className="px-10 pt-10"> <Image src={photo} alt="Shoes" className="rounded-xl" /> </figure> <div className="card-body items-center text-center"> <h2 className="card-title">{product.title}</h2> <p>{product.body}</p> <div className="card-actions"> <button className="btn btn-primary">Buy Now</button> </div> </div> </div> ))} </div> </div> ); }; export const getServerSideProps: GetServerSideProps<Products> = async () => { try { const response = await fetch("https://jsonplaceholder.typicode.com/posts"); const data = await response.json(); console.log(data); // Verify that data is being fetched correctly return { props: { data, }, }; } catch (error) { console.error(error); return { props: { data: [], }, }; } }; export default ExploreProducts;
我期望能正常获取API数据并在UI中展示。
问题排查与修复
1. Image组件缺少必要属性(核心问题)
Next.js的Image组件强制要求指定尺寸属性(width/height)或使用fill模式配合父容器定位,否则会抛出渲染错误,导致组件无法正常渲染,这是你看不到数据的直接原因。
2. 类型定义与默认值冗余
当前类型定义嵌套层级复杂,默认值写法可以简化,提升代码可读性。
3. 缺失API响应校验
在getServerSideProps中添加响应状态码校验,能更精准定位API请求失败的原因。
修改后的完整代码
import { GetServerSideProps, NextPage } from 'next'; import Image from 'next/image'; import React from 'react'; import photo from '../../assets/photo.jpg'; // 拆分类型定义,结构更清晰 type Product = { id: number; title: string; body: string; }; type ProductsProps = { data?: Product[]; }; // 直接定义空数组作为默认值 const defaultData: Product[] = []; const ExploreProducts: NextPage<ProductsProps> = ({ data = defaultData }) => { console.log(data); return ( <div> <div className='grid grid-cols-12 gap-5'> {data.map(product => ( <div className="card w-96 bg-base-100 shadow-xl" key={product.id}> <figure className="px-10 pt-10 relative w-full h-48"> {/* 使用fill模式配合父容器定位,适配tailwind布局 */} <Image src={photo} alt="Shoes" className="rounded-xl object-cover" fill /> </figure> <div className="card-body items-center text-center"> <h2 className="card-title">{product.title}</h2> <p>{product.body}</p> <div className="card-actions"> <button className="btn btn-primary">Buy Now</button> </div> </div> </div> ))} </div> </div> ); }; export const getServerSideProps: GetServerSideProps<ProductsProps> = async () => { try { const response = await fetch("https://jsonplaceholder.typicode.com/posts"); // 校验API响应状态,排查请求失败原因 if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } const data = await response.json(); console.log(data); return { props: { data, }, }; } catch (error) { console.error(error); return { props: { data: defaultData, }, }; } }; export default ExploreProducts;
内容的提问来源于stack exchange,提问作者S M Fahim Hossen
相关产品推荐
相关产品推荐

