React组件通信实现方式详解

1. 父子组件通信方式

✨父子组件之间的通信很常见,其中父组件可以通过props,原型方法向子组件通信,同时子组件也可以用回调函数,事件冒泡向父组件通信

父传子

原型方法

父组件通过React.createRef()创建Ref,保存在实例属性myRef上。父组件

中,渲染子组件时,定义一个Ref属性,值为刚创建的myRef。

父组件调用子组件的myFunc函数,传递一个参数,子组件接收到参数,打印出参数。

this.props

name作为props由父组件传递给子组件,子组件拿到name后,渲染在页面上。参数有父组件传递给子组件

import React, { Component, Fragment } from 'react';
class Son extends Component {
 myFunc(name) {
 console.log(name);
 }
 render() {
 return <></>;
 }
}
// 父组件
export default class Father extends Component {
 constructor(props) {
 super(props);
 // 创建Ref,并保存在实例属性myRef上
 this.myRef = React.createRef();
 }
 componentDidMount() {
 // 调用子组件的函数,传递一个参数
 this.myRef.current.myFunc('Jack');
 }
 render() {
 return (
 <>
 <Son ref={this.myRef} />
 </>
 );
 }
}

子传父

  • 回调函数
  • 事件冒泡

在子组件内部,修改了父组件中的值,从而完成了子组件向父组件通信

import React, { Component } from 'react'
class Navbar extends Component{
 render(){
 return <div style={{background:"red"}}>
 <button onClick={()=>{
 console.log("子通知父, 让父的isSHow 取反。",this.props.event) 
 this.props.event() //调用父组件传来啊的回调函数
 }}>click</button>
 <span>navbar</span>
 </div>
 }
}
class Sidebar extends Component{
 render(){
 return <div style={{background:"yellow",width:"200px"}}> 
 <ul>
 <li>11111</li>
 </ul>
 </div>
 }
}
export default class App extends Component {
 state = {
 isShow:false
 }
 handleEvent = ()=>{
 this.setState({
 isShow:!this.state.isShow
 })
 // console.log("父组件定义的event事件")
 }
 render() {
 return (
 <div>
 <Navbar event={this.handleEvent}/>
 {/* <button onClick={()=>{
 this.setState({
 isShow:!this.state.isShow
 })
 }}>click</button> */}
 {this.state.isShow && <Sidebar/>}
 </div>
 )
 }
}
/*
父传子 :属性,
子传父: 回调函数 callback
*/

2. 非父子组件通信方式

👉状态提升

React中的状态提升概括来说,就是将多个组件需要共享的状态提升到它们最近的父组件上.在父组件上改变这个状态然后通过props

👉发布订阅模式实现

👉context状态树传参

a. 先定义全局context对象
import React from 'react'
const GlobalContext = React.createContext()
export default GlobalContext
b. 根组件引入GlobalContext,并使用GlobalContext.Provider(生产者)
//重新包装根组件 class App {}
<GlobalContext.Provider
value={{
name:"kerwin",
age:100,
content:this.state.content,
show:this.show.bind(this),
hide:this.hide.bind(this)
}}
>
<之前的根组件></之前的根组件>
</GlobalContext.Provider>
c. 任意组件引入GlobalContext并调用context,使用GlobalContext.Consumer(消费者)
<GlobalContext.Consumer>
{
context => {
this.myshow = context.show; //可以在当前组件任意函数触发
this.myhide = context.hide;//可以在当前组件任意函数触发
return (
<div>
{context.name}-{context.age}-{context.content}
</div>
)
}
}
</GlobalContext.Consumer>

注意:GlobalContext.Consumer内必须是回调函数,通过context方法改变根组件状态

context优缺点:

优点:跨组件访问数据

缺点:react组件树种某个上级组件shouldComponetUpdate 返回false,当context更新时,不会引起下级组件更新

作者:糖^O^原文地址:https://blog.csdn.net/m0_61016904/article/details/129093764

%s 个评论

要回复文章请先登录注册