React之组件通讯(props使用,父传子,子传父,兄弟组件通讯,跨组件通讯)

一、组件通讯介绍

  • 组件时独立且封闭的单元,默认情况下,只能使用组件自己的数据
  • 在组件化过程中,通常会将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能
  • 而在这个过程中,多个组件之间不可避免的要共享某些数据
  • 为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通。这个过程就是组件通讯
  • 组件中的状态是私有的,也就是说,组件的状态只能在组件内部使用,无法直接在组件外使用

二、props基本使用与注意点

2.1 props基本使用

  • 使用场景: 组件接收外部数据
  • 作用: 接收(其他组件)传递给当前组件的数据
  • 传递: 给组件标签添加属性
  • 接收: 函数组件通过props参数接收 类组件通过this.props

核心代码

import React from 'react'

import ReactDOM from 'react-dom/client'

//创建函数组件 直接通过props
const Hello = (props) => {
  console.log('函数组件传递的值', props)
  return <div>我是函数组件</div>
}

//创建类组件  通过this.props
class Hello1 extends React.Component {
  render() {
    console.log('类组件传递的值', this.props)
    return <div>我是类组件</div>
  }
}

const h1 = (
  <h1>
    {/* 函数组件传值 */}
    <Hello name="张三" age={19}></Hello>
    {/* 类组件传值 */}
    <Hello1 name="李四" age={19}></Hello1>
  </h1>
)

ReactDOM.createRoot(document.querySelector('#root')).render(h1)

2.2 注意点

  • props是只读对象,无法修改
    • 单向数据流(自上而下)
    • 表示: 父组件中的数据可以通过 props 传递给子组件,并且,当父组件中的数据更新时,子组件就会自动接收到最新的数据
    • 类比:就像瀑布的水一样只能从上往下流动,并且,当上游的水变浑浊,下游的水也会受到影响
  • 可以传递任意数据(数字 字符串 布尔类型 数组 对象 函数 jsx)

三、父传子

  • 步骤
    • 1.父组件提供要传递的state数据
    • 2.给子组件标签添加属性,值为state中的数据
    • 3.子组件中通过props接收父组件中传递的数据

核心代码

  • 父组件
class Parent extends React.Component {
  state = {
    money: 10000
  }
  render() {
    const { money } = this.state
    return (
      <div>
        <h1>我是父组件:{money}</h1>
        {/* 将数据传递给子组件 */}
        <Child money={money} />
      </div>
    )
  }
}
  • 子组件
function Child(props) {
	return (
  	<div>
      {/* 接收父组件中传递过来的数据 */}
    	<h3>我是子组件 -- {props.money}</h3>
    </div>
  )
}

四、子传父

  • 步骤
    • 1.父组件提供一个回调函数(用于接收数据)
    • 2.将该函数作为属性的值 传递给子组件
    • 3.子组件通过props 调用回调函数
    • 4.将子组件的数据作为参数传递给回调函数

核心代码

  • 父组件
class Parent extends React.Component {
  state = {
    money: 10000
  }
	// 回调函数
	buyPhone = price => {
    this.setState({
      money: this.state.money - price
    })
  }
  render() {
    const { money } = this.state
    return (
      <div>
        <h1>我是父组件:{money}</h1>
        {/* 传递给子组件 */}
        <Child money={money} buyPhone={this.buyPhone} />
      </div>
    )
  }
}
  • 子组件
const Child = (props) => {
  const handleClick = () => {
    // 子组件调用父组件传递过来的回调函数
		props.buyPhone(100)
  }
  return (
    <div>
      <h3>我是子组件 -- {props.money}</h3>
      <button onClick={handleClick}>买手机</button>
    </div>
  )
}

五、兄弟组件

  • 状态提升
  • 将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态
  • 公共父组件职责
    • 1.提供共享状态
    • 2.提供操作共享状态的方法
  • 要通讯的子组件只需通过 props 接收状态或操作状态的方法

状态提升前

在这里插入图片描述

状态提升后

在这里插入图片描述

核心代码

  • 父组件
import React, { Component } from 'react'
import ReactDOM from 'react-dom'

// 导入两个子组件
import Jack from './Jack'
import Rose from './Rose'

// App 是父组件
class App extends Component {
  // 1. 状态提升到父组件
  state = {
    msg: '',
  }

  changeMsg = msg => {
    this.setState({
      msg,
    })
  }
  
  render() {
    return (
      <div>
        <h1>我是App组件</h1>
        {/* 兄弟组件 1 */}
        <Jack say={this.changeMsg}></Jack>
				{/* 兄弟组件 2 */}
        <Rose msg={this.state.msg}></Rose>
      </div>
    )
  }
}

// 渲染组件
ReactDOM.createRoot(document.querySelector('#root')).render(<App />)
  • 子组件A 修改值
import React, { Component } from 'react'

export default class Jack extends Component {
  say = () => {
    // 修改数据
    this.props.say('you jump i look')
  }
  render() {
    return (
      <div>
        <h3>我是Jack组件</h3>
        <button onClick={this.say}></button>
      </div>
    )
  }
}
  • 子组件B 接收修改的值
import React, { Component } from 'react'

export default class Rose extends Component {
  render() {
    return (
      <div>
        {/* 展示数据 */}
        <h3>我是Rose组件-{this.props.msg}</h3>
      </div>
    )
  }
}

六、跨组件通讯 Context

  • 组件之间的层级关系,除了以上两种常见的情况外,还有一种不太常见的情况,那就是:远房亲戚关系(也就是两个组件之间间隔较远)

在这里插入图片描述
在这里插入图片描述

  • 实现方式: 使用 Context 来实现跨组件传递数据
  • Context 上下文,可以理解一个范围,只要在这个范围内容,就可以直接跨组件传递数据

核心代码

// 0 导入创建 context 的函数
import { createContext } from 'react'

// 1 创建 Context 对象
//	 createContext 的返回值是一个 对象
//	 对象中包含了两个组件,分别是: Provider 状态的提供者组件(提供状态)  Consumer 状态的消费者组件(使用状态)
const { Provider, Consumer } = createContext()

// 2 使用 Provider 组件包裹整个应用,并通过 value 属性提供要共享的数据
<Provider value="blue">
  <div className="App">
    <Node /> 
  </div>
</Provider>

// 3 使用 Consumer 组件接收要共享的数据
<Consumer>
  {color => <span>data参数表示接收到的数据 -- {color}</span>}
</Consumer>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gik99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值