在react中使用vuex的示例代碼
前言
筆者最近在學習使用react,提到react就繞不過去redux。redux是一個狀態(tài)管理架構(gòu),被廣泛用于react項目中,但是redux并不是專為react而生,兩者還需要react-redux建立一座橋梁。同時,redux架構(gòu)規(guī)定只能發(fā)送同步action,要想發(fā)送異步action就需要結(jié)合中間件如redux-thunk、redux-saga等,所以說要想搞定redux還真是不容易啊,光名詞就這么多。筆者以前也接觸過一點vuex,vuex對筆者這樣的菜雞相對友好,但是vuex是和vue配套的,是不可能用在react中的,這輩子都別想用在react中。但是我不服,那么這篇文章就探索下如何制作一個可以在react中使用的類似vuex的狀態(tài)管理工具,我將它取名為reux。
vuex <=> redux + react-redux + redux-saga
正文
響應式數(shù)據(jù)觀測系統(tǒng)
vue的一大特色就是響應式數(shù)據(jù)觀測系統(tǒng),它可以在get數(shù)據(jù)時收集依賴,在set數(shù)據(jù)時觸發(fā)更新。vuex借助于vue的數(shù)據(jù)觀測系統(tǒng),可以輕松的收集數(shù)據(jù)依賴,并且依賴可以精細到組件的粒度,也就是說某一狀態(tài)改變時,只有依賴到這一狀態(tài)的組件才會觸發(fā)rerender,這樣看來redux體系就比較傻,只要提交action,就會從根組件rerender(react-redux內(nèi)部自動進行shouldCompoentUpdate判斷)。

上圖來自于vue官網(wǎng)對vuex架構(gòu)的說明,鏈接。
上圖中的component是vue component,只要vue component執(zhí)行render,那么vuex的數(shù)據(jù)響應系統(tǒng)就可以自動的收集依賴,當狀態(tài)改變時,依賴于此狀態(tài)的組件就會重新渲染。既然我們要實現(xiàn)的是一個類vuex的狀態(tài)管理工具,即支持以get的方式收集依賴,以set的方式觸發(fā)更新,所以reux利用了vue的響應式數(shù)據(jù)觀測系統(tǒng),正所謂前人種樹,后人乘涼。
如何收集依賴
我們已經(jīng)有了響應式數(shù)據(jù)系統(tǒng),接下來要解決的問題就是如何收集依賴,收集依賴必須要觸發(fā)get,而觸發(fā)get的前提是組件可以拿到store,因此第一步是向組件注入store。類似react-redux,reux提供了Provider使子組件可以拿到store。
class Provider extends Component {
getChildContext() {
return {store: this.props.store};
}
render() {
const { children } = this.props;
return children;
}
}
Provider.childContextTypes = {
store: PropTypes.object
};
相應的子組件可以context拿到store,如下
class Child extends Component {
render() {
// store => this.context.store
}
}
Child.contextTypes = {
store: PropTypes.object
};
這樣寫的缺點顯而易見,每個子組件都需要定義contextTypes,同樣的類似于react-redux,reux提供了connect函數(shù),用于映射state => props
const connect = (mapStateToProps = () => {}) => {
return (WrappedComponent) => {
const Wrapper = class extends Component {
render() {
const store = this.context.store;
const props = Object.assign({}, this.props, mapStateToProps(store.state, this.props), {dispatch: store.dispatch, commit: store.commit});
return <WrappedComponent {...props} />
}
}
Wrapper.contextTypes = {
store: PropTypes.object
};
reaturn Wrapper;
}
}
這樣一來,只要組件執(zhí)行render方法,便會觸發(fā)get鉤子,從而使得store自動收集依賴,我們再想下依賴是什么,其實依賴應該是組件實例,那么當set鉤子觸發(fā)時,每個依賴(即組件實例)只要執(zhí)行forceUpdate方法就可以達到rerender的效果。
但是問題是,get鉤子觸發(fā)時,如何確定依賴到底是誰呢?借鑒vue,我們定義一個stack,當componentWillMount時進棧,當componentDidMount時出棧
componentWillMount() {
pushTarget(this);
}
componentDidMount() {
popTarget(this);
}
這樣當get鉤子觸發(fā)時,當前target就是目標依賴。同時應當注意,當組件update時應當重新收集依賴,因為update之后依賴關(guān)系很可能已經(jīng)變化了
update() {
// 清空依賴
this.clear();
pushTarget(this);
this.forceUpdate(() => {
popTarget(this);
})
}
至此,我們的小目標已經(jīng)完成了,在react中使用vuex不再是夢!
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
React Native 集成 ArcGIS 地圖的詳細過程
ArcGIS官方提供了 JavaScript SDK,也提供了 ArcGIS-Runtime-SDK-iOS,但是并沒有提供 React Native的版本,所以這里使用了 react-native-arcgis-mapview 庫,本文給大家介紹React Native 集成 ArcGIS 地圖的詳細過程,感興趣的朋友跟隨小編一起看看吧2024-06-06

