React 观察者模式解决组件间通信 不推荐 (推荐使用redux)
目的:主要通过该案例学习观察者模式
基于观察者模式来解决组件通信
一个组件订阅消息 一个组件发布消息
在组件中订阅消息,消息的回调函数可以接收数据,可以访问组件实例对象 所以可以用接收的数据更新组件的状态实现通信,这种基于状态实现通信的方案就是reflux的实现
观察者模式只是用来发布消息的框架,不能数据存储,所以在订阅之前发布的消息就丢失了。
import React, { Component } from "react";
import {render} from 'react-dom';
// 利用观察者模式修改state
// 重点
let Observer = (function() {
// 定义消息管道
let _msg = {};
return{
// 注册消息 参数消息类型(名称) 回调函数
// 注册消息将回调函数注册到该类型的消息管道中
on(type, callback) {
// 判断该消息类型是否已注册
if(_msg[type]) {
_msg[type].push(callback)
}else{
// 不存在创建新的
_msg[type] = [callback]
}
},
// 发布消息 参数 消息类型 传递参数
trigger(type, ...args) {
// 判断存在并遍历回调函数并传递参数
_msg[type] && _msg[type].forEach(callback => callback(...args))
},
// 注销消息
off(type, callback){
// 有该回调函数
if(callback) {
// 判断有没有该类型
if(_msg[type]) {
// 注销该类型下面的该回调函数
let index = _msg[type].indexOf(callback)
// 判断该类型下有没有回调函数
if(index >= 0) {
// 删除
_msg[type].splicce(index, 1)
}
}
// 有该数据类型
}else if (type) {
// 清空
_msg[type] = []
}else{
// 清空全部
_msg = {}
}
}
}
})()
class App extends Component {
delNum() {
Observer.trigger('delNum', 2)
}
render() {
return (
{/* 父子间通信 */}
{/* 兄弟间通信 */}
)
}
}
class AddNum extends Component {
render() {
return (
)
}
}
class ShowNum extends Component {
constructor(props) {
super(props);
this.state = {
num: 0
}
}
// 组件创建完成
componentDidMount() {
// 注册消息
Observer.on('delNum', num => {
this.setState({num: this.state.num - num})
})
Observer.on('addNum', num => {
this.setState({num: this.state.num + num})
})
}
render() {
return (
num:{this.state.num}
)
}
}
// 观察者模式只是一个通信框架,因此不会存储数据,在订阅消息之前发布的消息会丢失
// Observer.trigger('addNum', 10);
// 结果为0
render( , app);
// Observer.trigger('addNum', 10);、
// 结果为10