React 06

1 React 组件 props 概念与使用

  • props 本质与作用 :props 可类比为 "可调节的旋钮",作用和函数参数一致,是 React 组件的唯一参数,以对象形式存在。例如在 function Avatar(props) 中,props 就是包含所有传入属性的对象,可通过 props.person、props.size 来访问具体属性。
  • 解构优化 :实际开发中通常不需要整个 props 对象,可对其进行解构,使代码更简洁,比如可将 let person = props.person; let size = props.size; 优化为函数参数的解构形式 function Avatar({ person, size })。

补充背景:这种设计让 React 组件的参数传递更灵活,能像配置项一样动态调整组件的表现,是组件化开发中实现复用和定制的核心机制之一。

2 props并不总是静态的,props是不可变的

  • props 的动态性 :组件的 props 并非静态,会随时间变化。例如 time prop 每秒更新、color prop 随用户选择变化,它反映了组件在任意时间点的数据状态。
  • props 的不可变性:props 是 "不可变" 的,组件自身无法直接修改 props。若需变更,需由父组件传递新的 props 对象,旧 props 会被丢弃并由 JavaScript 引擎回收内存。
  • 开发注意事项:不要尝试在组件内部 "更改 props",若需响应用户输入(如修改颜色),应通过 "设置 state" 来实现,可进一步学习 "State:组件的记忆" 相关内容。

补充背景:这种设计是 React 数据流动(单向数据流)的核心体现,确保了组件数据的可预测性,让状态管理更清晰,是 React 组件化开发中维护数据一致性的关键机制。

3 props摘要

规则类型 具体说明 背景与拓展
传递 props 像 HTML 属性一样添加到 JSX 中即可传递 props。 是组件间数据传递的基础方式,让父组件能向子组件传递配置信息。
读取 props 可通过函数参数解构语法(如 function Avatar({ person, size }))读取 props。 解构能简化代码,让开发者更直观地访问 props 中的具体属性。
默认值设置 可为 props 指定默认值(如 size = 100),用于处理缺少值或值为 undefined 的情况。 提升组件的健壮性,避免因 props 缺失导致的异常。
展开语法转发 可使用 <Avatar {...props} /> 这样的 JSX 展开语法转发所有 props,但不建议过度使用。 适合批量传递 props 场景,但过度使用会降低代码可读性和可维护性。
children prop 嵌套的 JSX(如 <Card><Avatar /></Card>)会被视为父组件(Card)的 children prop。 是实现组件嵌套、布局复用的重要机制,让组件能包含任意子内容。
props 不可变性 Props 是只读的时间快照,每次渲染会收到新版本,且组件自身不能修改 props。若需交互性,应设置 state。 这是 React 单向数据流的体现,确保数据可预测;state 则用于处理组件内部的可变状态,二者分工明确

应用props

javascript 复制代码
import { getImageUrl } from './utils.js';

export default function Gallery() {
  return (
    <div>
      <h1>Notable Scientists</h1>
      <section className="profile">
        <h2>Maria Skłodowska-Curie</h2>
        <img
          className="avatar"
          src={getImageUrl('szV5sdG')}
          alt="Maria Skłodowska-Curie"
          width={70}
          height={70}
        />
        <ul>
          <li>
            <b>Profession: </b> 
            physicist and chemist
          </li>
          <li>
            <b>Awards: 4 </b> 
            (Nobel Prize in Physics, Nobel Prize in Chemistry, Davy Medal, Matteucci Medal)
          </li>
          <li>
            <b>Discovered: </b>
            polonium (chemical element)
          </li>
        </ul>
      </section>
      <section className="profile">
        <h2>Katsuko Saruhashi</h2>
        <img
          className="avatar"
          src={getImageUrl('YfeOqp2')}
          alt="Katsuko Saruhashi"
          width={70}
          height={70}
        />
        <ul>
          <li>
            <b>Profession: </b> 
            geochemist
          </li>
          <li>
            <b>Awards: 2 </b> 
            (Miyake Prize for geochemistry, Tanaka Prize)
          </li>
          <li>
            <b>Discovered: </b>
            a method for measuring carbon dioxide in seawater
          </li>
        </ul>
      </section>
    </div>
  );
}

修改后

javascript 复制代码
import { getImageUrl } from './utils.js';

function Profile({
  imageId,
  name,
  profession,
  awards,
  discovery,
  imageSize = 70
}) {
  return (
    <section className="profile">
      <h2>{name}</h2>
      <img
        className="avatar"
        src={getImageUrl(imageId)}
        alt={name}
        width={imageSize}
        height={imageSize}
      />
      <ul>
        <li><b>Profession:</b> {profession}</li>
        <li>
          <b>Awards: {awards.length} </b>
          ({awards.join(', ')})
        </li>
        <li>
          <b>Discovered: </b>
          {discovery}
        </li>
      </ul>
    </section>
  );
}

export default function Gallery() {
  return (
    <div>
      <h1>Notable Scientists</h1>
      <Profile
        imageId="szV5sdG"
        name="Maria Skłodowska-Curie"
        profession="physicist and chemist"
        discovery="polonium (chemical element)"
        awards={[
          'Nobel Prize in Physics',
          'Nobel Prize in Chemistry',
          'Davy Medal',
          'Matteucci Medal'
        ]}
      />
      <Profile
        imageId='YfeOqp2'
        name='Katsuko Saruhashi'
        profession='geochemist'
        discovery="a method for measuring carbon dioxide in seawater"
        awards={[
          'Miyake Prize for geochemistry',
          'Tanaka Prize'
        ]}
      />
    </div>
  );
}

要理解在这个组件中如何使用 props,我们可以把重复的 profile 模块抽成独立组件 ,通过 props 传递不同科学家的信息(姓名、头像 ID、职业、奖项、发现等)。这样能让代码更复用、更易维护,也能清晰展示 props 的作用。

步骤 1:创建可复用的 ScientistProfile 子组件

把每个科学家的信息封装成一个组件,通过 props 接收外部传入的数据:

javascript 复制代码
// 新建 ScientistProfile.jsx 文件
import { getImageUrl } from './utils.js';

export default function ScientistProfile(props) {
  // 通过 props 接收父组件传递的所有科学家信息
  const { name, imageId, profession, awards, discovered } = props;

  return (
    <section className="profile">
      <h2>{name}</h2>
      <img
        className="avatar"
        src={getImageUrl(imageId)}
        alt={name}
        width={70}
        height={70}
      />
      <ul>
        <li>
          <b>Profession: </b> 
          {profession}
        </li>
        <li>
          <b>Awards: {awards.length} </b> 
          {awards.join(', ')}
        </li>
        <li>
          <b>Discovered: </b>
          {discovered}
        </li>
      </ul>
    </section>
  );
}

原来的 Gallery 组件作为父组件 ,向 ScientistProfile 子组件传递不同的 props(每个科学家的具体数据):

javascript 复制代码
import { getImageUrl } from './utils.js';
import ScientistProfile from './ScientistProfile.jsx'; // 引入子组件

export default function Gallery() {
  return (
    <div>
      <h1>Notable Scientists</h1>
      {/* 传递第一个科学家的 props */}
      <ScientistProfile
        name="Maria Skłodowska-Curie"
        imageId="szV5sdG"
        profession="physicist and chemist"
        awards={[
          "Nobel Prize in Physics",
          "Nobel Prize in Chemistry",
          "Davy Medal",
          "Matteucci Medal"
        ]}
        discovered="polonium (chemical element)"
      />
      {/* 传递第二个科学家的 props */}
      <ScientistProfile
        name="Katsuko Saruhashi"
        imageId="YfeOqp2"
        profession="geochemist"
        awards={[
          "Miyake Prize for geochemistry",
          "Tanaka Prize"
        ]}
        discovered="a method for measuring carbon dioxide in seawater"
      />
    </div>
  );
}

对 props 用法的详细解释

  1. 什么是 props? props 是 "properties" 的缩写,是 React 中父组件向子组件传递数据的方式 。可以把它理解成 "组件的参数"------ 就像函数通过参数接收外部输入,组件通过 props 接收父组件的输入。

  2. 如何传递 props? 在父组件中使用子组件时,像写 HTML 属性一样添加自定义属性即可。例如 <ScientistProfile name="xxx" imageId="xxx" /> 中,name、imageId 等就是传递给子组件的 props。

  3. 如何读取 props? 子组件的函数参数就是 props 对象。可以直接通过 props.xxx 读取,也可以像上面的例子一样用解构赋值 (const { name, imageId } = props)来简化代码。

  4. props 的特点

    • 只读性 :子组件不能修改 props 的值(要修改需通过父组件重新传递)。
    • 动态性 :父组件可以随时传递新的 props,子组件会自动重新渲染。

通过这种**"抽离组件 + 传递 props"** 的方式,你可以清晰地看到 props 是如何在组件间传递数据的,也能体会到它让代码复用、维护更高效的优势。

相关推荐
卷无止境41 分钟前
ECharts:把数据变成故事的可视化利器
前端
Eric_见嘉1 小时前
在职前端 Skill 和 MCP 分享
前端·后端·agent
liangshanbo12151 小时前
面试题:如何优化 Webpack 的打包速度?
前端·webpack·node.js
wengad1 小时前
从 wangEditor 迁到 wangEditor-next
前端·javascript·vue.js
an12321212 小时前
ARM嵌入式学习笔记:SPI通信协议详解
arm开发·笔记·学习
by209992 小时前
从结构体到对象:正式学习C++类的骨架、封装与this指针
c++·经验分享·学习
乌暮2 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习
行者-全栈开发2 小时前
【前端/JS框架】CVE-2026-3854:GitHub Enterprise Server X-Stat注入XSS漏洞深度剖析与紧急修复指南
前端·javascript·github
计算机魔术师3 小时前
AMD砸82亿买下李飞飞,这次不卖芯片卖什么?
前端
小雪崩3 小时前
嵌入式学习 day60:ARM汇编——触摸屏与SPI
汇编·arm开发·学习