react-关于props的理解
前言大白话理解:比如说当你写了一个组件,但是需要该组件从外部传值给组件内部,然后执行组件内部的代码,让组件重新渲染后显示到网页。这个时候就需要props对象,注意三点:
- 他是对象,不是什么方法,不是什么函数,不是什么api!!!
- props 是组件的唯一参数! React 组件函数只能接受的参数是一个
props
对象!!! - 他的主要目的是外部传值给组件内部,不是让组件重新渲染后显示到网页!!!那是stats要做的!!!
- 组件与函数基本阔以理解为一个东西
那么问题来了,不是什么方法或者函数他怎么传值到组件内部呢?详情如下
如何将 Props 传递给子组件
方法一(在组件内部声明变量)
要有变量才能传值,现在不理解先看下文
一、声明一个变量(在创建组件的括号里面)
大白话理解:这个props很像html中元素的属性就比如说,img
标签里面的属性。但是,这是不完全一样滴。
<img
className="avatar"
src="https://i.imgur.com/1bX5QH6.jpg"
alt="Lin Lanying"
width={100}
height={100}
/>
这个里面有一坨属性,然后你思考一下,这一坨属性是怎么作用在这个元素(组件)内部的?你把这个组件当作函数就行
然后回到我们创建一个组件这个环节
function Avatar() {//创建了一个名为Avantar的组件
return (
//然后下面就是这个组件的逻辑等等
<img
className="avatar"
src="https://i.imgur.com/1bX5QH6.jpg"
alt="Lin Lanying"
width={100}
height={100}
/>
);
}
既然要传值就要声明一个变量对吧,哪这个变量放哪呢?如下
function Avatar(props) {****}
很简单,就如同创建函数时一样,把这个变量放到这个函数(组件)的括号中就能实现像函数那样传参了。既然上文说他是一个对象,哪当然这个对象中有属性,因此我们可以直接在这个函数(组件)中声明这个对象的属性,而不用写props.属性1什么什么的,这是直接默认放在props里面了
function Avatar({属性1,属性2,3,4,5.....}){****}
也因此,这个props对象拥有了属性,我们可以任意的传参了。但是为啥括号里面有花括号,上面的props没有呢?因为这是jsx的语法,有{}是为了说明他是个对象,本身就是对象就不用说明了。哪你有对象吗?
额外提一下,这个props对象里面也可以放对象,怎么处理呢?看下文
二、给变量赋值(发生在return里面)
有变量了该怎么赋值呢?哪当然是在使用这个组件的时候给组件赋值呗
传递两个 props:person
(一个对象)和 size
(一个数字)此时props对象里面就声明了一个名为person的对象与名为size的数字
//组件内部
function Avatar({ person, size }) {
// 声明这个两个变量
}
//组件外部
export default function Profile() {
return (
<Avatar
//赋值给这两个变量
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
}
然后就赋值了呗,简简单单是吧。要使用变量就在组件内部的函数体里面写逻辑就行了,不懂就看《如何在子组件中读取props》
方法二(在组件外部声明)
**我们再思考一层:**假如说组件里面有一坨的属性,有几十个属性,难道我得一个个在括号里面一个个声明吗?
哪当然是不用的,除开阔以在组件的括号里面声明,还阔以在组件的外部声明或者说是在组件被调用的时候,也就是他的尖括号里面声明
一、声明一个变量,同时给变量赋值
声明变量
//组件外部
export default function Profile() {
return (
<div>
<Avatar
size={100}//声明的名为size的属性
person={{ //声明的名为person对象的属性
name: 'Katsuko Saruhashi',
imageId: 'YfeOqp2'
}}
/>)}
解构props
//组件内部
function Avatar(props) {
let person = props.person;
let size = props.size;
//或者使用es6语法解构
let { person, size } = props;
}
如何在子组件中读取props
有传入就有传出,如同函数一样,组件也有自己的“函数体”
使用方法一时:
function Avatar({ person, size }) {//声明person, size这两个属性
return (
<img
className="avatar"
src={getImageUrl(person)}//getImageUrl一个方法(我还没写)
alt={person.name}//使用该变量
width={size}//使用该变量
height={size}//使用该变量
/>
);
}
传入的值就写入了img
标签的属性里面了
使用方法二时:
先结构props,再调用
function Avatar(props) {
let person = props.person;//结构props
let size = props.size;
<img
className="avatar"
src={getImageUrl(person)}//getImageUrl一个方法(我还没写)
alt={person.name}//使用该变量
width={size}//使用该变量
height={size}//使用该变量
/>
}
而外部是:
//组件外部
export default function Profile() {
return (
<div>
<Avatar
size={100}
person={{
name: 'Katsuko Saruhashi',
imageId: 'YfeOqp2'
}}
/>)}
//组件内部
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
关于声明后读取所述:
用大白话说就是,这个props里面属性的声明可以放在组件内部的括号“()”之中,也阔以放在调用该组件的尖括号“<>”之中,但是不能放在组件内部的“函数体”之中。
如何组件之间传递props
首先需要明确的是父子组件与父子元素之间的关系:
- 父子组件是父组件在创建中调用子组件所称
- 父子元素是html文档中上下两个元素的继承关系所称
组件之间传递props
function Profile({ person, size, isSepia, thickBorder }) {//声明了一坨属性
return (
//这个组件的逻辑
<div className="card">
<Avatar
person={person}//使用该变量
size={size}//使用该变量
isSepia={isSepia}//使用该变量
thickBorder={thickBorder}//使用该变量
/>
</div>
);
}
等效于:
//创建Profile组件,把Avatar组件作为他的子组件
function Profile(props) {//
return (
<div className="card">
<Avatar {...props} />//将他所有的 props 转给了 Avatar 组件,而不列出每个名字
</div>
);
}
其中的...props
是jsx中的展开语法
关于使用jsx标签作为子组件传递的理解
这个东东和html中的<div><div/>
标签很相似,相似之处在于div是当作一个容器把子元素给包裹起来,如:
<div>
<img/>
</div>
而使用jsx标签作为子组件,你先把jsx标签看作组件来
//创建组件
function Card({ children }) {//声明一个叫children的变量(这个变量之所以这么命名是因为里面要存的是子组件的props)
return (
<div className="card">
{children}//不理解没关系,反正是一个对象
</div>
);
}
创建了如上组件,就形同创建了一个跟<div><div/>
标签作用非常相似的东西
//使用<Card>组件与<Avatar>组件是
//<Avatar>组件是<Card>组件的子组件
export default function Profile() {
return (
<Card>
<Avatar//在<Card>组件中放入<Avatar>组件
size={100}
person={{
name: 'Katsuko Saruhashi',
imageId: 'YfeOqp2'
}}
/>
</Card>
);
}
在<Card>
组件中放入<Avatar>
组件后,因为<Card>
声明的{ children }在两个div之间,<Card>
组件因此阔以包裹任意嵌套内容(或者说组件),就如react官方文档所言:将带有 children
prop 的组件看作有一个“洞”,可以由其父组件使用任意 JSX 来“填充”。你会经常使用 children
prop 来进行视觉包装:面板、网格等等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MrYwsmju-1689755725693)(.\img\react-关于props的理解-图1.png)]
关于Props 随时间变化
如同官方文档所说:一个组件可能会随着时间的推移收到不同的 props。,因此Props 并不总是静态的!
当一个组件需要改变它的 props(例如,响应用户交互或新数据)时,它不得不“请求”它的父组件传递 不同的 props —— 一个新对象!它的旧 props 将被丢弃,最终 JavaScript 引擎将回收它们占用的内存。
最后的最后,虽然说props阔以做这些事情,但是不要尝试“更改 props”。 当你需要响应用户输入(例如更改所选颜色)时,你可以“设置 state。
]
关于Props 随时间变化
如同官方文档所说:一个组件可能会随着时间的推移收到不同的 props。,因此Props 并不总是静态的!
当一个组件需要改变它的 props(例如,响应用户交互或新数据)时,它不得不“请求”它的父组件传递 不同的 props —— 一个新对象!它的旧 props 将被丢弃,最终 JavaScript 引擎将回收它们占用的内存。
最后的最后,虽然说props阔以做这些事情,但是不要尝试“更改 props”。 当你需要响应用户输入(例如更改所选颜色)时,你可以“设置 state。