React-关于props的理解【两千字大白话讲解】

react-关于props的理解

前言大白话理解:比如说当你写了一个组件,但是需要该组件从外部传值给组件内部,然后执行组件内部的代码,让组件重新渲染后显示到网页。这个时候就需要props对象,注意三点:

  1. 他是对象,不是什么方法,不是什么函数,不是什么api!!!
  2. props 是组件的唯一参数! React 组件函数只能接受的参数是一个 props 对象!!!
  3. 他的主要目的是外部传值给组件内部,不是让组件重新渲染后显示到网页!!!那是stats要做的!!!
  4. 组件与函数基本阔以理解为一个东西

那么问题来了,不是什么方法或者函数他怎么传值到组件内部呢?详情如下


如何将 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

首先需要明确的是父子组件与父子元素之间的关系

  1. 父子组件是父组件在创建中调用子组件所称
  2. 父子元素是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。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值