React 的 Props 与组件通讯

企业项目实战 > 第二部分 > React 基础回顾

React 的 Props 与组件通讯

什么是 Props

当 React 元素为用户自定义组件时, 它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件, 这个对象就被称之为 “props”。

props 是一个从外部传进组件内的参数, 由于 React 具有单向数据流的特性, 所以它的主要作用是从父组件向子组件中传递数据, 它是不可变的, 如果想要改变它, 只能通过外部组件传入新的 props 来重新渲染子组件, 否则子组件的 props 和展示形式不会改变。

props 除了可以传字符串, 数字, 还可以传递对象, 数组甚至是回调函数。

归纳起来一句话:props 是一个对象, 可以接受几乎所有类型的属性, 它是组件用来接收父组件传入的参数的, 不允许在该组件内部进行改变, 而只能通过父组件来修改。

实例:组件的调用与 props
function Welcome(props) {
   
  return <h1>Hello, {
   props.name}</h1>;
}

class App extends React.Component {
   
  return (
    <div>
      {
   /*我们在这里, 使用刚刚定义的组件名, 就可以直接调用这个组件, 其内部的属性, 就是组件即将接收到的props参数*/}
      <Welcome name="abc" />
    </div>
  );
}

state 与 props 的不同点与相同点

不同点:

  1. 初始值来源: state 的初始值来自于自身的 getInitalState(constructor) 函数
    props 来自于父组件或者自身 getDefaultProps( 若 key 相同 props 的值会被 state 的值覆盖 )
  2. 修改方式: state 只能在自身组件中 setState, 不能由父组件修改
    props 只能由父组件修改, 不能在自身组件修改
  3. 对子组件: state 代表的是一个组件内部自身的状态, 只能在自身组件中存在
    props 是一个由父组件传递给子组件的数据流, 这个数据流可以一直传递到子孙组件

相同点: 1. props 和 state 都是导出 HTML 的原始数据
2. 都能由自身组件的相应初始化函数设定初始值
3. props 和 state 的改变都会触发 render 的重新渲染
4. props 和 state 都是纯 JS 对象(用 typeof 来判断, 结果都是 object)

通过 props 实现父传子的通讯

这是最简单也是最常用的一种通讯方式:父组件通过向子组件传递 props,子组件得到 props 后进行相应的处理,如同我们刚才用于解释 props 的这段代码,App 做为一个父组件,将 name 通过 props 传入子组件由子组件进行处理后渲染到 view 中。

通过 props 中的回调函数实现子传父的通讯

在解释什么是 props 时,我们知道了,props 不仅仅可以传递字符串和数字这些基本类型对象,也能传递函数、对象等引用类型的属性。所以,我们可以利用回调函数来实现子组件向父组件通讯:父组件将一个函数作为 props 传递给子组件,子组件调用该回调函数,便可以向父组件通讯

function Welcome(props) {
   
  return <h1 onClick={
   props.nameClick}>Hello, {
   props.name}</h1>;
}

class App extends React.Component {
   
  constructor(props) {
   
    super(props)
    // 所有需要绑定this对象的处理函数,尽量在constructor中绑定
    // 因为每一次bind都会生成一个新的函数,如果写在jsx中就会导致每次调用或渲染时都会生成一个新的函数
    // 这是一种不专业的表现,合格的前端要合理使用并珍惜每一分资源
    this.nameClick = this.nameClick.bind(this)
  }
  nameClick() {
   
    console.log(this, '#######')
  }
  return (
    <div>
      <Welcome name="abc" nameClick={
   this.nameClick} />
    </div>
  );
}
使用 Context 实现跨级组件通讯

所谓跨级组件通讯,就是父组件向子组件的子组件通讯,向更深层的子组件通讯。
我们可以使用 props 层层向下传递来实现爷孙组件通讯,但如果父组件结构较深,那么中间的每一层组件都要去传递 props,无疑增加了复杂度,并且这些 props 并不是这些中间组件自己所需要的, 可能组件层次在三层以内时我们可以采用这种方式,但当组件嵌套过深时,采用这种方式就需要斟酌了。

所以在这里我们推荐使用 context 来实现多级嵌套的组件通讯,React 中的 Context 相当于一个全局变量,是一个大容器,我们可以把要传递的状态放在这个容器中,这样一来,不管嵌套有多深,都可以随意取用。

// 函数组件没办法通过 ContextType 来挂载 Context, 但可以通过 Consumer来获取 Context内容
function Son(props) {
   
  return (
    // Consukmer 需要一个函数做为子元素,这个函数接收当前的 Context 值并且返回一个React节点
    // 传递给函数的 value 值来自于组件树上方离这个 Context 最近的 Provider 提供的 value 值
    <TestContext.Consumer>
      {
   ({
   name, clickName}) => (<span onClick={
   clickName}>{
   name}</span>)}
    </TestContext.Consumer>
  )
}
// 中间层什么都不知道
function Welcome(props) {
   
  return <h1>Hello, <Son /
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值