React 18 组件通信 将props传递给子组件

news/2024/11/6 13:32:06/

参考文章

将 Props 传递给组件

React 组件使用 props 来互相通信。每个父组件都可以提供 props 给它的子组件,从而将一些信息传递给它。

Props 类似于HTML 标签属性,可以通过它们传递任何 JavaScript 值,包括对象、数组和函数。

通过标签属性传递 props

Props 是传递给 JSX 标签的信息。例如,classNamesrcaltwidthheight 便是一些可以传递给 <img> 的 props:

function Avatar() {return (<imgclassName="avatar"src="https://i.imgur.com/1bX5QH6.jpg"alt="Lin Lanying"width={100}height={100}/>);
}export default function Profile() {return (<Avatar />);
}

可以传递给 <img> 标签的 props 是预定义的(ReactDOM 符合 HTML 标准)。

也可以将任何 props 传递给自定义组件,例如 Avatar ,以便自定义它们。 就像上面这样!

向组件传递 props

在这段代码中, Profile 组件没有向它的子组件 Avatar 传递任何 props :

export default function Profile() {return (<Avatar />);
}

可以分两步给 Avatar 一些 props。

步骤 1: 将 props 传递给子组件

首先,将一些 props 传递给 Avatar。例如,传递两个 props:person(一个对象)和 size(一个数字):

export default function Profile() {return (<Avatarperson={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}size={100}/>);
}

注意:如果 person= 后面的双花括号让你感到困惑,请记住,在 JSX 花括号中,它们只是一个对象。

现在,可以在 Avatar 组件中读取这些 props 了。

步骤 2: 在子组件中读取 props

可以通过在 function Avatar 之后直接列出它们的名字 person, size 来读取这些 props。这些 props 在 ({}) 之间,并由逗号分隔。这样,可以在 Avatar 的代码中使用它们,就像使用变量一样。

function Avatar({ person, size }) {// 在这里 person 和 size 是可访问的
}

向使用 personsize props 渲染的 Avatar 添加一些逻辑,就完成了。

现在可以配置 Avatar ,通过不同的 props,使它能以多种不同的方式进行渲染。

import { getImageUrl } from './utils.js';function Avatar({ person, size }) {return (<imgclassName="avatar"src={getImageUrl(person)}alt={person.name}width={size}height={size}/>);
}export default function Profile() {return (<div><Avatarsize={100}person={{ name: 'Katsuko Saruhashi', imageId: 'YfeOqp2'}}/><Avatarsize={80}person={{name: 'Aklilu Lemma', imageId: 'OKS67lh'}}/></div>);
}

Props 使你独立思考父组件和子组件。 例如,可以改变 Profile 中的 personsize props,而无需考虑 Avatar 如何使用它们。 同样,可以改变 Avatar 使用这些 props 的方式,不必考虑 Profile

可以将 props 想象成可以调整的“旋钮”。它们的作用与函数的参数相同 —— 事实上,props 正是 组件的唯一参数! React 组件函数接受一个参数,一个 props 对象:

function Avatar(props) {let person = props.person;let size = props.size;// ...
}

通常不需要整个 props 对象,所以可以将它解构为单独的 props。

注意:在声明 props 时, 不要忘记 () 之间的一对花括号 {}

function Avatar({ person, size }) {// ...
}

这种语法被称为 “解构”,等价于于从函数参数中读取属性:

function Avatar(props) {let person = props.person;let size = props.size;// ...
}

给 prop 指定一个默认值

如果想在没有指定值的情况下给 prop 一个默认值,可以通过在参数后面写 = 和默认值来进行解构:

function Avatar({ person, size = 100 }) {// ...
}

现在, 如果 <Avatar person={...}/> 渲染时没有 size prop, size 将被赋值为 100

默认值仅在缺少 size prop 或 size={undefined} 时生效。 但是如果传递了 size={null}size={0},默认值将 被使用。

使用 JSX 展开语法传递 props

有时候,传递 props 会变得非常重复:

function Profile({ person, size, isSepia, thickBorder }) {return (<div className="card"><Avatarperson={person}size={size}isSepia={isSepia}thickBorder={thickBorder}/></div>);
}

重复代码没有错(它可以更清晰)。但有时可能会重视简洁。一些组件将它们所有的 props 转发给子组件,正如 Profile 转给 Avatar 那样。因为这些组件不直接使用他们本身的任何 props,所以使用更简洁的“展开”语法是有意义的:

function Profile(props) {return (<div className="card"><Avatar {...props} /></div>);
}

这会将 Profile 的所有 props 转发到 Avatar,而不列出每个名字。

请克制地使用展开语法。 如果在所有其他组件中都使用它,那就有问题了。 通常,它表示应该拆分组件,并将子组件作为 JSX 传递。

将 JSX 作为子组件传递

嵌套浏览器内置标签是很常见的:

<div><img />
</div>

有时会希望以相同的方式嵌套自定义组件:

<Card><Avatar />
</Card>

当将内容嵌套在 JSX 标签中时,父组件将在名为 children 的 prop 中接收到该内容。例如,下面的 Card 组件将接收一个被设为 Avatarchildren prop 并将其包裹在 div 中渲染:

import Avatar from './Avatar.js';function Card({ children }) {return (<div className="card">{children}</div>);
}export default function Profile() {return (<Card><Avatarsize={100}person={{ name: 'Katsuko Saruhashi',imageId: 'YfeOqp2'}}/></Card>);
}

尝试用一些文本替换 <Card> 中的 <Avatar>,看看 Card 组件如何包裹任意嵌套内容。它不必“知道”其中渲染的内容。会在很多地方看到这种灵活的模式。

可以将带有 children prop 的组件看作有一个“洞”,可以由其父组件使用任意 JSX 来“填充”。会经常使用 children prop 来进行视觉包装:面板、网格等等。

Props 如何随时间变化

下面的 Clock 组件从其父组件接收两个 props:colortime

export default function Clock({ color, time }) {return (<h1 style={{ color: color }}>{time}</h1>);
}

这个例子说明,一个组件可能会随着时间的推移收到不同的 props。 Props 并不总是静态的!在这里,time prop 每秒都在变化。当选择另一种颜色时,color prop 也改变了。Props 反映了组件在任何时间点的数据,并不仅仅是在开始时。

然而,props 是 不可变的(一个计算机科学术语,意思是“不可改变”)。当一个组件需要改变它的 props(例如,响应用户交互或新数据)时,它不得不“请求”它的父组件传递 不同的 props —— 一个新对象!它的旧 props 将被丢弃,最终 JavaScript 引擎将回收它们占用的内存。

不要尝试“更改 props”。 当需要响应用户输入(例如更改所选颜色)时,可以“设置 state”。

摘要

  • 要传递 props,请将它们添加到 JSX,就像使用 HTML 属性一样。
  • 要读取 props,请使用 function Avatar({ person, size }) 解构语法。
  • 可以指定一个默认值,如 size = 100,用于缺少值或值为 undefined 的 props 。
  • 可以使用 <Avatar {...props}/> JSX 展开语法转发所有 props,但不要过度使用它!
  • <Card><Avatar /></Card> 这样的嵌套 JSX,将被视为 Card 组件的 children prop。
  • Props 是只读的时间快照:每次渲染都会收到新版本的 props。
  • 不能改变 props。当需要交互性时,可以设置 state。

http://www.ppmy.cn/news/169289.html

相关文章

Ansible基础五——条件语句、循环语句、handlers、任务失败处理

文章目录 一、 循环语句1.1 单量循环1.2 多量循环1.3 老版本用法1.4 loopregister 二、条件判断2.1 根据变量状态判断2.2 根据变量是否存在判断2.3 根据事实判断2.4 多条件判断2.4.1 and用法2.4.2 or用法 2.5 循环判断2.6 根据上个任务结果判断 三、handlers处理程序四、任务失…

GitLab从旧服务器迁移到新服务器(空间不足,gitlab安装报错)

注意事项&#xff1a;迁移前首先要保证新旧服务器上的GitLab版本号一致&#xff0c;而且gitlab的包要符合安装的系统gitlab安装&#xff0c;系统与安装包不一致导致的安装错误。 1.查看当前GitLab版本 cat /opt/gitlab/embedded/service/gitlab-rails/VERSION显示为 12.5.5。…

C++11:智能指针

目录 1、智能指针含义 2、智能指针的分类 1、智能指针含义 &#xff08;1&#xff09;C智能指针是一种用于管理动态内存的指针&#xff0c;可以自动进行内存管理&#xff0c;避免了手动管理内存所带来的问题。 &#xff08;2&#xff09;智能指针的核心思想是资源分配即初始…

IP地址、子网划分

目录 一、IP地址1.IP地址表示2.分类IP地址3.无分类编址 CIDR4.特殊IP地址 二、子网划分1.子网、子网掩码、子网划分VLSM2.网络地址、广播地址3.示例1&#xff1a;等分为两个子网3.1 划分前&#xff1a;3.2 划分后&#xff1a; 4.示例2&#xff1a;等分为四个子网3.1 划分前&…

Arthas 的简单使用

安装 Arthas 根据操作系统&#xff0c;从Arthas 官方 GitHub 仓库下载相应的 Arthas 安装包。 执行 Arthas 打开命令行工具&#xff0c;进入 Arthas 安装目录并执行以下命令&#xff1a; java -jar arthas-boot.jar 在启动时&#xff0c;Arthas 会自动检测到本机上所有运行…

2021年全球与中国净水器行业市场规模及发展前景分析

2021年全球与中国净水器行业市场规模及发展前景分析 本报告研究全球与中国市场净水器的发展现状及未来发展趋势&#xff0c;分别从生产和消费的角度分析净水器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品…

反渗透、超滤和电渗析技术的区别

净水器的品牌系列比较多&#xff0c;大多采用两种过滤技术&#xff0c;即反渗透和超滤&#xff0c;所以&#xff0c;净水器产品也按技术分为两类&#xff0c;其一是以RO反渗透净水器为代表的纯净水机&#xff0c;另一种是以超滤机为代表的超滤净水机。 反渗透 反渗透&#xf…

小米净水器更换滤芯步骤和水龙头亮黄灯的解决办法

【开篇序言】 众所周知&#xff0c;无论何种品牌的净水器&#xff0c;滤芯都是有一定使用寿命的&#xff0c;而不是一次性安装可永久使用&#xff0c;如果遇到无需换滤芯这类宣布&#xff0c;请远离&#xff0c;不靠谱。换滤芯&#xff0c;小米净水器也不例外&#xff0c;小米…