『React』组件传递与接收多个属性:从基础到优雅写法
点赞 + 关注 + 收藏 = 学会了
在 React 开发中,我们经常需要给子组件传递多个属性(比如给一个博客卡片组件传递标题、作者、发布时间等)。如果逐个传递会显得繁琐,而 React 提供了简洁的语法来处理这种场景。本文就来详细讲解:如何高效传递多个属性,以及子组件如何优雅地接收这些属性。
给子组件传递多个属性:从基础到简写
假设我们有一个展示博客文章的子组件BlogCard
,需要接收title
(标题)、author
(作者)、date
(日期)、content
(内容)4 个属性。我们来看看传递这些属性的几种方式。
1、基础方式:逐个传递属性
最直接的方式是在使用子组件时,逐个写出属性名和对应的值:
// 父组件中使用BlogCardfunction ParentComponent() { // 假设这是要传递的数据 const blogTitle = \"React属性传递指南\"; const blogAuthor = \"前端小白\"; const blogDate = \"2025-10-01\"; const blogContent = \"本文讲解如何传递多个属性...\"; return ( <div> {/* 逐个传递属性 */} <BlogCard title={blogTitle} author={blogAuthor} date={blogDate} content={blogContent} /> </div> );}
这种方式的问题很明显:当属性数量多的时候,代码会变得冗长,而且容易遗漏或写错属性名。
2、极简方式:使用扩展运算符(...
)
React 中最推荐的写法是使用扩展运算符(...
),它可以把一个对象的所有属性 “拆分” 成单独的键值对,一次性传递给子组件:
function ParentComponent() { const blog = { title: \"React属性传递指南\", author: \"前端小白\", date: \"2025-10-01\", content: \"本文讲解如何传递多个属性...\" }; return ( <div> {/* 用...扩展运算符传递所有属性,等价于逐个传递 */} <BlogCard {...blog} /> </div> );}
关键说明:
{...blog}
等价于 title={blog.title} author={blog.author} date={blog.date} content={blog.content}
,但代码简洁得多!
这种语法叫 “属性展开”,是 React 中传递多个属性的 “语法糖”,极大减少了重复代码。
3、混合用法:扩展运算符 + 额外属性
如果需要在展开对象的同时,额外添加或覆盖某个属性,直接写在后面即可(后面的属性会覆盖前面的):
function ParentComponent() { const blog = { title: \"React属性传递指南\", author: \"前端小白\", date: \"2025-10-01\", }; return ( // 展开blog的同时,添加content属性,覆盖date属性 <BlogCard {...blog} content=\"本文讲解如何传递多个属性...\" // 新增属性 date=\"2025-10-02\" // 覆盖原有date属性 /> );}
这样既利用了扩展运算符的简洁,又能灵活调整个别属性,非常实用。
子组件如何优雅地接收多个属性?
传递属性后,子组件需要接收并使用这些属性。如果直接用props.xxx
的方式访问,在属性多的时候会很繁琐。React 中推荐用 “对象解构” 来优雅地接收属性。
1. 基础方式:通过props
对象访问
子组件接收的所有属性都会被包装在一个props
对象中,我们可以直接通过props.属性名
访问:
// 子组件BlogCard(基础写法)function BlogCard(props) { return ( <div style={{ border: \'1px solid #ddd\', padding: \'15px\', margin: \'10px\' }}> <h2>{props.title}</h2> <p>作者:{props.author} | 日期:{props.date}</p> <p>{props.content}</p> </div> );}
这种方式适合属性较少的情况,当属性多了(比如 5 个以上),反复写props.
会很冗余。
2. 优雅方式 1:解构赋值(直接提取需要的属性)
使用对象解构,可以在函数参数中直接提取需要的属性,省去props.
前缀:
// 子组件BlogCard(解构写法)function BlogCard({ title, author, date, content }) { // 直接使用title、author等变量,无需props. return ( <div style={{ border: \'1px solid #ddd\', padding: \'15px\', margin: \'10px\' }}> <h2>{title}</h2> <p>作者:{author} | 日期:{date}</p> <p>{content}</p> </div> );}
优点:
- 代码更简洁,减少重复的
props.
- 一眼就能看出组件需要哪些属性,可读性更高
3. 优雅方式 2:解构时设置默认值
如果父组件可能忘记传递某些属性(比如date
可能没传),可以在解构时设置默认值,避免undefined
导致的错误:
// 解构时给属性设置默认值function BlogCard({ title = \"默认标题\", // 如果没传title,就用\"默认标题\" author = \"匿名作者\", // 默认作者 date = \"2025-01-01\", // 默认日期 content = \"暂无内容\" // 默认内容}) { return ( <div style={{ border: \'1px solid #ddd\', padding: \'15px\', margin: \'10px\' }}> <h2>{title}</h2> <p>作者:{author} | 日期:{date}</p> <p>{content}</p> </div> );}
场景:当属性不是 “必填” 时,默认值能保证组件在缺少属性时也能正常显示,增强健壮性。
4. 优雅方式 3:深层解构(处理嵌套属性)
如果传递的属性中包含嵌套对象(比如user: { name: \'张三\', age: 20 }
),可以用深层解构提取嵌套的属性:
// 父组件传递嵌套对象function Parent() { const data = { title: \"React进阶技巧\", user: { name: \"张三\", age: 28 } }; return <BlogCard {...data} />;}// 子组件深层解构function BlogCard({ title, user: { name, age } // 深层解构:从user对象中提取name和age}) { return ( <div> <h2>{title}</h2> <p>作者:{name}({age}岁)</p> </div> );}// 深层解构也可以设置默认值function BlogCard({ title, user: { name = \"匿名\", age = 0 } = {} // 注意:要给整个user对象也设默认值,避免user为undefined时报错}) { return <div>作者:{name}({age}岁)</div>;}
注意:深层解构时,如果父组件可能不传递外层对象(比如user
可能没传),需要给外层对象也设置默认值(如user = {}
),否则会报错 “Cannot destructure property ‘name’ of ‘undefined’ or ‘null’”。
5. 优雅方式 4:提取剩余属性(过滤不需要的属性)
如果子组件只需要部分属性,而父组件传递了很多属性,可以用剩余运算符(...
) 收集剩余属性,避免代码冗余:
function BlogCard({ title, ...rest }) { // title是需要的属性,rest包含其他所有属性(author、date、content等) console.log(rest); // { author: \'前端小白\', date: \'2025-10-01\', content: \'...\' } return ( <div> <h2>{title}</h2> {/* 可以把剩余属性传递给子组件的子元素 */} <div {...rest} /> {/* 等价于 author={rest.author} date={rest.date} ... */} </div> );}
场景:当组件需要 “透传” 属性给内部的 HTML 元素或其他子组件时(比如给按钮组件传递onClick
、style
等原生属性),非常实用。
最佳实践总结
- 传递多个属性:
优先使用扩展运算符{...对象}
,简洁高效;需要新增 / 覆盖属性时,直接写在后面。 - 接收属性:
- 用对象解构
({ a, b, c })
提取需要的属性,减少props.
冗余; - 给非必填属性设置默认值,增强组件健壮性;
- 嵌套属性用深层解构,配合默认值避免报错;
- 多余属性用剩余运算符收集,方便透传。
- 用对象解构
完整示例:从传递到接收
我们把上面的知识整合起来,看一个完整的例子:
// 父组件:传递多个属性function App() { const article = { title: \"React属性传递最佳实践\", author: \"技术胖\", // 故意不传递date,测试默认值 content: \"本文总结了属性传递的实用技巧...\" }; return ( <div> <h1>我的博客</h1> {/* 用扩展运算符传递属性,同时添加一个额外属性 */} <BlogCard {...article} readTime=\"5分钟\" /> </div> );}// 子组件:优雅接收属性function BlogCard({ title = \"未命名文章\", author = \"匿名\", date = \"2025-01-01\", // 父组件没传,会用默认值 content = \"无内容\", readTime = \"3分钟\", ...other // 收集可能的其他属性(如果有的话)}) { return ( <div style={{ border: \'1px solid #eee\', borderRadius: \'8px\', padding: \'20px\', margin: \'10px 0\' }}> <h2>{title}</h2> <div style={{ color: \'#666\', margin: \'10px 0\' }}> 作者:{author} | 日期:{date} | 阅读时间:{readTime} </div> <p>{content}</p> {/* 透传剩余属性(如果有的话) */} <div {...other} /> </div> );}
运行后,你会看到一个完整的博客卡片,其中date
因为父组件没传递,自动使用了默认值 “2025-01-01”,其他属性正常显示。
通过这些技巧,你可以在 React 中高效地传递和接收多个属性,让代码更简洁、更易维护。记住:扩展运算符简化传递,解构赋值简化接收,这是 React 开发中的必备技能哦!
以上就是本文的全部内容啦,想了解更多React用法的工友可以关注《React 中文教程》
也可以➕我 green bubble 吹吹水咯
点赞 + 关注 + 收藏 = 学会了