react组件通信

react组件通信是一个常用功能,在做react项目中经常遇到
React组件层级关系 在了解Reat组件通讯之前,先了解下React层级关系。
父子:parent与child1、child2、child1-1、child2-1
兄弟:child1与child2、child1-1与child1-2...
React组件通讯 组件间通信大体有下面几种通讯方式:
1.父—>子:使用props
2.子—>父:使用props回调
3.兄弟组件通信:层层传递props;发布者订阅者模式
4.非嵌套组件间通信:发布者订阅者模式;redux
1.父—>子
父组件向子组件通信,用到比较多。在react中,数据流动是单向的,父组件通过向子组件传递props进行通信,子组件得到props进行相应处理。
patrent.js

import React,{Component} from 'react'; import Child1 from "./child1"; //子页面export class Parent extends Component { state = { msg:'parent' } render(){ return(父组件通过props向子组件通信: ) } } export default Parent;

child1.js
import React,{Component} from 'react'; export class child1 extends Component { render(){ return( {this.props.msg} //通过props接收父组件信息 ) } } export default child1;

如果父组件与子组件之间不止一个层级,如 parent 与child 、 child与child1_1 这样的关系,parent与child1_1通讯可通过 es6中... 扩展运算符进行通信
export class child1 extends Component { render(){ return({this.props.msg}
//多个层级通过扩展运算符...) } }

export class child1_1 extends Component { render(){ return( parent与child1_1通信:{this.props.msg} ) } }

2.子—>父
利用回调函数。
父组件向子组件传递 props ,只是父组件传递的是作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到父组件的作用域中。
parent.js
export class Parent extends Component { constructor(props) { super(props); this.state = { msg: 'parent', child2Msg:'' }; }msgCallback(msg) { this.setState({ child2Msg:msg }); } render(){ return(父组件通过props向子组件通信: 子组件通过回调函数向父组件通信:{this.state.child2Msg}
this.msgCallback(child2)} />) } }

child2.js
import React,{Component} from 'react'; export class child2 extends Component { render(){ return( ) } } export default child2;

对于层级比较深的子组件与父组件之间通讯,参照父组件与子组件通讯,仍可使用 ... 运算符,将父组件的调用函数传递给子组件
3.兄弟组件通信
A.层层组件传递props:
对于没有直接关系的两个组件,就如 child1 与 child2 之间,他们唯一的关联就是拥有相同的父组件parent。参考之前父子通讯方式,可以先通过 child1 向 parent 组件进行通讯,再由parent 向 child2 组件进行通讯,在这里不贴代码了。
不足:当Parent 的 state 发生变化,会触发 Parent 及Parent 的子组件的生命周期,在各个组件中的 componentDidUpdate 方法均被触发。
B.发布者—订阅者模式
这种方式可以避免上面的不足。发布者发布事件,订阅者监听事件并做出反应。
在这里需要一个事件系统,一个简单的事件系统是:
class Event { constructor() { this.listeners = {}; }on(type, cb, mode) { let cbs = this.listeners[type]; if (!cbs) { cbs = []; } cbs.push(cb); this.listeners[type] = cbs; return () => { this.remove(type, cb); }; }emit(type, ...args) { const cbs = this.listeners[type]; if (Array.isArray(cbs)) { for (let i = 0; i < cbs.length; i++) { const cb = cbs[i]; if (typeof cb === 'function') { cb(...args); } } } }remove(type, cb) { if (cb) { let cbs = this.listeners[type]; cbs = cbs.filter(eMap => eMap.cb !== cb); this.listeners[type] = cbs; } else { this.listeners[type] = null; delete this.listeners[type]; } } }export default new Event();

child1页面发布事件
import React,{Component} from 'react'; import Child1_1 from './child1_1'; import Event from '../../utils/event'export class child1 extends Component { componentDidMount() { setTimeout(() => { // 发布事件 Event.emit('child1','child1发布消息') }, 1000); } render(){ return({this.props.msg}
) } } export default child1;

child2页面接收事件
componentDidMount() { //接收事件 Event.on('child1', (msg) => { this.setState({ msg }); } ) }

我们可以看到,child1 组件的 componentDidMount 中发布了事件,child2 组件对事件做出响应,更新自身 state,在整个通讯过程中,只有 child2 发出了一次生命周期更新渲染。
4.redux
Redux是 JavaScript 状态容器,是第三方的状态管理器,提供可预测化的状态管理,是通讯的中间者。大中型项目可以使用redux,小项目就没什么必要了。redux介绍的东西太多了,在这里我就不具体介绍了,感兴趣的话,大家可以去了解下https://www.redux.org.cn/。
【react组件通信】以上若有错误或考虑不周之处,敬请指正,谢谢!

    推荐阅读