对react深入了解的同学都会意识到react其实就是一个consumer,而producer是数据。
数据源有3种,分别是props,state和api,我在这里分享下我的meng设计思路:一种用rxjs把这三种数据源合并为一个数据源(store$)的思路。
state
state$ = new ReplaySubject(1)
state$是我们合并之后的数据源store$的触发器,和react的setState类似,这里的用法是state$.next({})
props
props$ = Observable.of(this.props)
props只需要用of转换成流就行
api
cosnt api = state => fetch(`url/${state.id}`)
api$ = state$.flaMap(state => Observabe.fromPromise(api(state)))
merge$ =Observable.from([api1$,api2$,api3$,...]).mergeAll()
因为我们的api是需要监听state的,所以有新的状态之后api需要被flatMap,api可能不止一个,所以需要mergeAll帮我们剥掉一层observable
合并
store$ = Observable.merge(state$,props$,merge$)
订阅
store$.subscribe((state: S) => {
this.hasStoreStateChanged = true
this.setState(state)
})
触发
//更新state
state$.next(nextState)
//更新props
public componentWillReceiveProps(nextProps: P) {
state$.next(nextProps)
}
因为state改变之后,api会重新调用,所以api可以这么写
function(currentState,nextState){
if(currentState.id !== nextState.id){
fetch("url/"+nextState.id)
}
}
渲染
public render() {
this.hasStoreStateChanged = false
const props = Object.assign({ setState: rootStore.children[displayName].setState }, <S & P>this.state)
return createElement(component as ComponentClass<P>, props)
}
public shouldComponentUpdate() {
return this.hasStoreStateChanged
}
看到shouldComponentUpdate可以看到只有通过改变store$,才能触发组件重新render,所以在store$上面可以做些优化,这里省略