Next.js中Card组件解构传入props值为undefined的问题
问题场景
- 实现目标:遍历本地
db.json文件存储的portfolio项目数据,将每个项目对象传递给自定义的Card组件完成渲染。 - 基础情况:
Portfolio页面组件存放在pages文件夹下,组件内第15行的console.log可以正常打印读取到的json对象数组,输出格式为[ {}, {}, {} ]。
页面数据获取代码如下:
import React from "react" import Card from "../components/Card" export async function getStaticProps() { const res = await import("./db.json") return { props: { projects: res.projects, }, } }
Portfolio页面组件代码如下:
const portfolio = ({ projects }) => { // 该console.log可按预期正常输出项目数组 console.log(projects) return ( <div className='portfolio'> {projects.map((project, id) => ( <Card key={id} props={project} /> ))} </div> ) } export default portfolio
异常现象
- 渲染
Card组件时,图片无法加载,标题、跳转链接等所有字段都无法正常渲染,打印对应字段全部返回undefined
Card组件代码如下:
import React, { useState } from "react" import Image from "next/image" const Card = ({ image, title, github, demo }) => { console.log(title) const [hovered, setHover] = useState(false) return ( <div className='portfolio-card' onMouseEnter={() => setHover(!hovered)} onMouseLeave={() => setHover(!hovered)} > <div className='portfolio-card-info'> <h3 className='portfolio-card-title'>{title}</h3> {hovered && <p>ReactJs</p>} {hovered && <p>Recoil</p>} <ul className='portfolio-links'> <li> <a href={github}>Source</a> </li> <li> <a href={demo}>Demo</a> </li> </ul> </div> <Image className='portfolio-image' src={image} alt='portfolio-image' /> </div> ) } export default Card
- 控制台输出验证:
- Portfolio组件内的打印正常输出长度为3的项目对象数组:
Array(3) [ {…}, {…}, {…} ] - Card组件内打印
title字段输出undefined
- Portfolio组件内的打印正常输出长度为3的项目对象数组:
- React开发者工具检查:选中任意Card组件,能看到props确实已经传入组件。
问题原因
传参写法错误:渲染Card时写的是<Card key={id} props={project} />,相当于把整个项目对象挂在了Card组件props下名为props的属性上,Card组件顶层props里只有key和props两个字段,直接解构{ image, title, github, demo }自然拿不到值,所有字段都会返回undefined。这也是为什么React DevTools能看到props传入,但是解构拿不到值的原因——需要的字段都在props.props下面,不在顶层。
解决方案
优先选择第一种修复方式,代码可读性更高:
- 修改Portfolio组件中Card的传参写法,用展开运算符把project对象的字段平铺传入Card:
// 把原来的<Card key={id} props={project} /> 改成下面这行 <Card key={id} {...project} />
改完之后project里的image/title/github/demo字段会直接作为Card的顶层props传入,原有Card组件的解构逻辑不需要任何修改就能正常拿到值。
- 如果不想修改传参逻辑,也可以修改Card组件的解构写法,从嵌套的props字段里取值:
// 把原来的const Card = ({ image, title, github, demo }) => { 改成下面这行 const Card = ({ props: { image, title, github, demo } }) => {
不推荐第二种写法,给传入属性命名为props很容易和组件本身接收的props对象混淆,也是本次问题出现的核心诱因。
内容的提问来源于stack exchange,提问作者danimalcrackerzz
相关产品推荐
相关产品推荐

