接着上一节继续来看代码,每次通过 dispatch 修改状态之后都要重新调用 renderApp 去渲染,不然的话页面不会改变的,那么能不能智能一点,在每次调用 dispatch 的时候自动调用 renderApp 呢?
好像是可以的,将 renderApp 传入 dispatch ,在数据更新后,重新调用下就可以了。
但是,新的问题又来了,既然 state 是共享数据,那么使用的地方必然不止一处,如果数据更新了,需要调用的渲染函数也不止一个,dispatch 就会变得特别臃肿。
这里就要用到观察者模式了,修改 createStore 为如下代码
1 | function createStore(state,stateChanger){ |
我们在 createStore 里面定义了一个数组 events和一个新的方法 subscribe,可以通过 store.subscribe(event) 的方式给 subscribe 传入一个监听函数,这个函数会被 push 到 events 中。
每次修改数据时都会调用 dispatch ,而 dispatch 除了修改数据,还会遍历调用 events 数组里面的函数,这样就可以通过 subscribe 在 events 中注册事件,来进行数据改变之后的操作。
现在只要在使用到数据的地方,通过 subscribe 注册一个事件就可以在 dispatch 触发数据改变的时候,重新渲染使用到数据的地方。
全部代码修改如下
1 |
|
现在我们有了一个比较通用的 createStore,它可以产生一种我们新定义的数据类型 store,通过 store.getState 我们获取共享状态,而且我们约定只能通过 store.dispatch 修改共享状态。store 也允许我们通过 store.subscribe 监听数据数据状态被修改了,并且进行后续的例如重新渲染页面的操作。