当前位置: 首页 > ops >正文

React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?

系列回顾:
在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒,但一个真实的React应用是由许多组件组合而成的,就像搭积木一样。如果这些“积木”之间不能互相沟通、传递信息,那我们就无法搭建出复杂的结构。

欢迎来到React学习的第三站!

今天,我们要学习组件之间最基本、最重要的一种沟通方式:父组件向子组件传递数据。而实现这种沟通的“信使”,就是 Props

什么是Props?

Props (是 Properties 的缩CR) 就像是你在调用一个JavaScript函数时传递的参数。在React中,它就是父组件在调用子组件时,传递给子组件的“属性”或“数据”。

核心思想:

  • 父组件拥有数据。
  • 父组件通过属性的方式,把数据“塞”给子组件。
  • 子组件通过一个叫做props的对象,接收并使用这些数据。

一个重要的原则:Props是只读的。 子组件只能读取和使用从父组件传来的Props,但绝对不能修改它。这保证了数据流的单向性(从上到下),让应用状态更可预测。


实战:创建一个用户卡片

让我们通过一个非常常见的案例——“用户卡片”——来学习Props的用法。我们将创建一个UserProfile子组件,它专门用来显示用户的头像和名字。而用户的具体信息(头像URL和名字)将由它的父组件App来提供。

第一步:创建子组件 UserProfile.jsx

  1. 在你的项目里,找到 src 文件夹。

  2. src 文件夹下,右键 -> 新建文件,命名为 UserProfile.jsx

  3. 将下面的代码复制到 UserProfile.jsx 文件中:

    // src/UserProfile.jsxfunction UserProfile(props) {// 'props' 是一个对象,包含了父组件传递过来的所有属性console.log(props); // 可以在浏览器控制台看看 props 长什么样return (<div className="user-card"><img src={props.avatarUrl} alt={props.name} className="avatar" /><h2 className="user-name">{props.name}</h2></div>);
    }export default UserProfile;
    

    代码解释:

    • 我们的UserProfile组件接收一个参数props。React会自动把父组件传递的所有属性打包成一个对象,放进这个props里。
    • 在JSX中,我们通过props.avatarUrlprops.name来使用这些数据。
    • className是React中用来指定CSS类名的方式,它对应HTML中的class属性。

第二步:在父组件 App.jsx 中使用子组件并传递Props

现在,回到我们的App.jsx文件。我们将在这里“调用”刚刚创建的UserProfile组件,并像给HTML标签添加属性一样,把数据传递给它。

  1. 清空 App.jsx 并写入以下代码:

    // src/App.jsximport './App.css';
    import UserProfile from './UserProfile'; // 1. 导入子组件function App() {const userInfo = {name: 'React 小白',avatarUrl: 'https://zh-hans.react.dev/images/logo.svg' // 使用React官方Logo作为头像};return (<div><h1>我的用户卡片</h1>{/* 2. 使用子组件,并像HTML属性一样传递props */}<UserProfile name={userInfo.name} avatarUrl={userInfo.avatarUrl} /></div>);
    }export default App;
    

    代码解释:

    1. import UserProfile from './UserProfile';: 我们首先需要像导入普通模块一样,把子组件导入进来。
    2. 在JSX中,我们像使用一个自定义的HTML标签一样使用<UserProfile />
    3. 最关键的一步: 我们添加了nameavatarUrl这两个“属性”。
      • name={userInfo.name}: 这表示我们要传递一个名为name的prop,它的值是userInfo.name这个JavaScript变量的值。
      • avatarUrl={userInfo.avatarUrl}: 同理,传递一个名为avatarUrl的prop。

第三步:添加一点样式

为了让卡片更好看,我们给App.css添加一点简单的样式。打开src/App.css,用下面的代码替换原有内容:

/* src/App.css */
.user-card {border: 1px solid #ccc;border-radius: 8px;padding: 16px;text-align: center;width: 200px;margin: 20px auto;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}.avatar {width: 100px;height: 100px;border-radius: 50%;object-fit: cover;
}.user-name {margin-top: 12px;color: #333;
}

第四步:查看效果

现在,保存所有文件,回到你的浏览器。你应该能看到一个漂亮的用户卡片,上面有React的Logo和"React 小白"这个名字。

你已经成功地实现了父组件到子组件的数据传递!

Props的更多用法

1. 传递不同类型的数据

Props不仅可以传递字符串,还可以传递任何JavaScript支持的类型。

<UserProfilename="Tom"          // 字符串age={25}             // 数字 (注意使用花括号)isMember={true}      // 布尔值hobbies={['coding', 'reading']} // 数组profile={{ job: 'developer' }} // 对象sayHi={() => alert('Hello!')} // 函数
/>

2. 使用Props解构赋值,让代码更简洁

在子组件中,每次都写props.name有点繁琐。我们可以使用JS的解构赋值来简化它。

修改UserProfile.jsx

// function UserProfile(props) {
// 变为:
function UserProfile({ name, avatarUrl }) { // 直接在这里解构return (<div className="user-card">{/* 现在可以直接使用变量名 */}<img src={avatarUrl} alt={name} className="avatar" /><h2 className="user-name">{name}</h2></div>);
}

这样代码是不是清爽多了?这是现代React开发中非常推荐的做法。


总结与思考

今天,我们掌握了组件化开发中最重要的一环——组件间的通信。回顾一下核心知识:

  1. Props是什么? 它是父组件传递给子组件的数据,就像函数的参数。
  2. 如何传递Props? 在使用子组件时,像写HTML属性一样把数据“塞”进去:<MyComponent propName={value} />
  3. 如何接收Props? 子组件的函数接收一个props对象作为参数,通过props.propName来访问数据。
  4. Props是只读的! 子组件不能修改从父组件接收到的Props。

我们现在已经学会了组件的“自力更生”(State)和“向父辈求助”(Props)。但是,一个有生命力的应用,还需要能响应用户的各种操作,比如点击、输入等等。

在下一篇文章 《React事件处理:如何给按钮绑定onClick点击事件?》 中,我们将学习如何让我们的组件“听懂”用户的指令,从而构建出真正可交互的应用。我们下期再会!

http://www.xdnf.cn/news/12921.html

相关文章:

  • 「混合开发」H5与原生App交互流程方案全面解析
  • SQL Server 手动收缩ldf文件
  • QEMU源码全解析 —— 块设备虚拟化(26)
  • Mac flutter环境搭建
  • MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
  • Linux系统部署KES
  • 中国高等职业教育(专科)专业划分
  • C# 求圆面积的程序(Program to find area of a circle)
  • 探索Selenium:自动化测试的神奇钥匙
  • 牛客round95D
  • 20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题
  • Electron 防脱壳转二进制 JSC 打包过程以及踩坑记录
  • 103页战略设计的核心:麦肯锡思维框架、分析方法与实施路径
  • AI会取代IT从业者吗?
  • 【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
  • C语言变量存储与指针:基础篇
  • 【HTML-16】深入理解HTML中的块元素与行内元素
  • Coze工作流-语音故事创作-文本转语音的应用
  • Ansible+Zabbix-agent2快速实现对多主机监控
  • 13.Websocket
  • WebRTC(一):整体架构
  • 【STM32】G030单片机开启超过8个ADC通道的方法
  • mongodb源码分析session执行handleRequest命令find过程
  • [ linux-系统 ] 进程控制
  • UNECE R79——解读自动驾驶相关标准法规
  • C++中vector类型的介绍和使用
  • 生成对抗网络(GAN)损失函数解读
  • 使用MFC中的CEvent实现两个线程之间的交替打印
  • 【Linux系统】Linux环境变量:系统配置的隐形指挥官
  • Gemini 2.5 Pro (0605版本) 深度测评与体验指南