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 (
            <div>
                {/* 父子间通信 */}
                <button onClick={e => this.delNum()}>减少2</button>
                <hr/>
                {/* 兄弟间通信 */}
                <AddNum></AddNum>
                <hr/>
                <ShowNum></ShowNum>
            </div>
        )
    }
}
class AddNum extends Component {
    render() {
        return (
            <div>
                <button onClick={e => Observer.trigger('addNum', 5)}>增加5</button>
            </div>
        )
    }
}
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 (
        <div>
            <h1>num:{this.state.num}</h1>
        </div>
       )
    }
}
// 观察者模式只是一个通信框架,因此不会存储数据,在订阅消息之前发布的消息会丢失
// Observer.trigger('addNum', 10);
// 结果为0
render(<App></App>, app);
// Observer.trigger('addNum', 10);、
// 结果为10
复制代码

 

posted @   子悔君  阅读(416)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示