在我们实际开发中使用mobx一般是应该与状态存储,当我们页面使用的状态可能在其他页面或者全局中要使用,我们一般处理的方案是1.存储在全局的store 里面,2. 存储在Windows里面 3. 缓存,但是如果数据比较大,而且我们要通过接口去把最新的数据存储到数据库,获取也会通过接口去查询获取,那我们就没有必要去使用缓存或者存储到我们windows系统里面增加缓存,我们一般在实例创建store,大致流程: 事件处理action => 更新state => state更新可能会触发computed => 触发auturun 或者reaction
在我们实际store的处理我们可能涉及不知一个store,公共的commonStore ,每一个模块可能也会涉及到自己维护的数据的store ,那如果这个页面触发事件,但是在另外一个页面需要去监听到这个事件我们如何处理呢? 那我们可能就需要 EventEmitter 这个来进行事件处理的
EventEmitter
一般在vue项目里面会涉及到兄弟组件传值调用,例如Vue里面的的兄弟组件传值,我们一般是定义一个store,把兄弟组件的方法放在store里面,然后根据state的状态的改变去触发行为的事件,或者使用公共的bus,然后兄弟组件通过订阅发布者模式可以监听和触发变化 一:创建一个EventBus (本质上是Vue的一个实例对象)
const EventBus = new Vue()
export default EventBus
二:将EventBus挂载到全局
import bus from "EventBus的文件路径"
Vue.prototype.bus = bus
三: 订阅事件
this.bus.$on('someEvent',func)
四: 发布事件
this.bus.$emit('someEvent',params)
这里react项目我们可以使用eventEmitter3来发布订阅事件:
- on() // 监听事件
- once() // 监听事件一次 on 和once的区别在于最后一个参数来决定是只监听一次
- emit() // 触发事件
触发事件: 要有事件-> 1. 事件存在 并且只监听一次,触发完毕直接卸载事件, 否则就根据arguments长度触发相应的事件回调 2. 事件不存在,遍历listener,判断listerens 上面是否存在事件,就循坏1 的判断
- getEvents() // 获取所有的监听事件
- addListener // 添加事件
- off() // 取消监听
- removeListener // 移除事件
- removeAllListeners // 移除所有事件
实例参考
import React, { Component } from 'react'
//一: 导入EventEmitter
import { EventEmitter } from 'events';
//二: 构建事件实例
const EventBus = EventEmitter()
//tips:我们可以在多个组件中去增加同一个事件的订阅,这里仅仅是示例
class Observer extends Component {
componentDidMount () {
// 三: 增加事件订阅
this.event1 = EventBus.addListener("someEvent", (params) => {
console.log(params)
})
}
componentWillUnMount () {
//四: 移除事件订阅
EventBus.removeListener(this.event1)
}
render () {
return (
<div>
事件监听组件
</div>
)
}
}
class Publisher extends Component {
handleClick () {
const params = {}
//五: 发布事件(当someEvent发布时,订阅该事件的函数就会执行)
EventBus.emit('someEvent', params)
}
render () {
return (
<div>
<button onClick={this.handleClick.bind(this)}>发布事件</button>
</div>
)
}
}
总结: 其实思想都是使用发布订阅者模式来监听事件和回调事件,目的减少状态的存储
mobx 知识容易忽略的地方
const lastpriceMap = observable.map({});
const lastprice = lastpriceMap.get(market);
lastpriceMap.set(market, '1');
第一次 fireImmediately: false 渲染不会触发
第一次 fireImmediately: true渲染会触发
reaction(
() => this.orgid.value,
() => {
console.log(this.orgid.value)
},
{ fireImmediately: true }
);