react-redux
是基于context
的特性实现了父子组件的状态共享,查看组件Provider
源码我们可以发现很多有用的信息:
Provider.propTypes = {
store: PropTypes.shape({
subscribe: PropTypes.func.isRequired,
dispatch: PropTypes.func.isRequired,
getState: PropTypes.func.isRequired
}),
context: PropTypes.object,
children: PropTypes.any
};
store
属性必须带有函数subscribe
,dispatch
和getState
。
subscribe
的作用是订阅更新,getState
获取最新 state,而dispatch
的作用是通过mapDispatchToProps
传给子组件去调用的。
这里,subscribe
扮演了很重要的角色,它通知了状态的更新,让Provider
能更新本地的状态storeState
,然后通过context
的特性实现子组件状态的更新!具体细节可以查看Provider
源码中subscribe
函数的实现细节。
subscribe() {
const { store } = this.props
this.unsubscribe = store.subscribe(() => {
// 详情省略
});
}
以上分析我们是不是可以想到:react-redux
给我们提供了一个 API 接口,只要实现了subscribe
,dispatch
和getState
,我们就能自己实现一个状态管理库?
当然可以,接下来开始实现一个简单的状态管理库。
class Store {
private _observers = [];
private _currentState = {};
constructor(initialState) {
this._currentState = initialState;
}
dispacth(type/*no-use*/, payload) {
// 处理state
const newState = {
...this.getState(),
...payload
};
this._setState(newState);
}
getState(){
return this._currentState;
}
private _setState(state) {
this._currentState = state;
this._notify();
}
private subscribe(fn/*Function*/){
//订阅方法,返回可取消订阅函数,这点很重要
this._observers.push(fn);
return () => {
this._observers = this._observers.filter(f => f !== fn);
}
};
private _notify(fn/*Function*/) {
//执行所有订阅
this._observers.forEach(fn => fn());
};
}
以上就是状态库的简单实现。当然可以实现更复杂的,这依赖于我们的创造力!
附上一个类似Vuex
的react状态管理库的实现,点击链接查看。