摘要:原文地址前言筆者最近在學習使用,提到就繞不過去。同時應當注意,當組件時應當重新收集依賴,因為之后依賴關系很可能已經變化了清空依賴至此,我們的小目標已經完成了,在中使用不再是夢
原文地址
前言筆者最近在學習使用react,提到react就繞不過去redux。redux是一個狀態管理架構,被廣泛用于react項目中,但是redux并不是專為react而生,兩者還需要react-redux建立一座橋梁。同時,redux架構規定只能發送同步action,要想發送異步action就需要結合中間件如redux-thunk、redux-saga等,所以說要想搞定redux還真是不容易啊,光名詞就這么多。筆者以前也接觸過一點vuex,vuex對筆者這樣的菜雞相對友好,但是vuex是和vue配套的,是不可能用在react中的,這輩子都別想用在react中。但是我不服,那么這篇文章就探索下如何制作一個可以在react中使用的類似vuex的狀態管理工具,我將它取名為reux。
vuex <=> redux + react-redux + redux-saga正文
響應式數據觀測系統
vue的一大特色就是響應式數據觀測系統,它可以在get數據時收集依賴,在set數據時觸發更新。vuex借助于vue的數據觀測系統,可以輕松的收集數據依賴,并且依賴可以精細到組件的粒度,也就是說某一狀態改變時,只有依賴到這一狀態的組件才會觸發rerender,這樣看來redux體系就比較傻,只要提交action,就會從根組件rerender(react-redux內部自動進行shouldCompoentUpdate判斷)。
上圖來自于vue官網對vuex架構的說明,鏈接。
上圖中的component是vue component,只要vue component執行render,那么vuex的數據響應系統就可以自動的收集依賴,當狀態改變時,依賴于此狀態的組件就會重新渲染。既然我們要實現的是一個類vuex的狀態管理工具,即支持以get的方式收集依賴,以set的方式觸發更新,所以reux利用了vue的響應式數據觀測系統,正所謂前人種樹,后人乘涼。
如何收集依賴
我們已經有了響應式數據系統,接下來要解決的問題就是如何收集依賴,收集依賴必須要觸發get,而觸發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函數,用于映射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} } Wrapper.contextTypes = { store: PropTypes.object }; reaturn Wrapper; } }
這樣一來,只要組件執行render方法,便會觸發get鉤子,從而使得store自動收集依賴,我們再想下依賴是什么,其實依賴應該是組件實例,那么當set鉤子觸發時,每個依賴(即組件實例)只要執行forceUpdate方法就可以達到rerender的效果。
但是問題是,get鉤子觸發時,如何確定依賴到底是誰呢?借鑒vue,我們定義一個stack,當componentWillMount時進棧,當componentDidMount時出棧
componentWillMount() { pushTarget(this); } componentDidMount() { popTarget(this); }
這樣當get鉤子觸發時,當前target就是目標依賴。同時應當注意,當組件update時應當重新收集依賴,因為update之后依賴關系很可能已經變化了
update() { // 清空依賴 this.clear(); pushTarget(this); this.forceUpdate(() => { popTarget(this); }) }
至此,我們的小目標已經完成了,在react中使用vuex不再是夢!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96381.html
摘要:我在中寫了這段代碼在組件被創建時候將會執行此函數相當于進入頁面的自執行使用方法監聽屬性并執行一個回調函數按道理在元素被創建的時候,會將監聽到的值賦給并且打印。 天地不仁以萬物為芻狗,宇宙無義視眾生如螻蟻 ——蕭鼎和我 上一節列出了5個關鍵點,第一個路由已經解決了,接下來解決第二個問題: 組件的通信問題 一、組件的關系 組件之間的關系無非就是兩種父子關系...
摘要:也就是說不應該有公開的,所有都應該是私有的,只能有公開的。允許使用方法設置監聽函數,一旦發生變化,就自動執行這個函數。用一個叫做的純函數來處理事件。可以通過得到當前狀態。在中,同步的表現就是發出以后,立即算出。 這篇文章試著聊明白這一堆看起來挺復雜的東西。在聊之前,大家要始終記得一句話:一切前端概念,都是紙老虎。 不管是Vue,還是 React,都需要管理狀態(state),比如組件之...
摘要:說到老四了,最苦逼的家伙了,活都讓他干了,活總得干完一個說一個吧,所以他基本上同步進行的。 前言 這次發表的項目,這對我來說是一場革命。記錄著第一次GitHub發布項目,記錄著最初學習vuex的頭昏腦脹,也記錄著懷揣對react的一腔熱血后卻步履闌珊后,再次回看vue時那種感覺。所以說這個項目對我很有意思,麻雀雖小,五臟俱全。 在寫這個項目之前,我正在試水react,那種函數式編程+j...
摘要:將注意力集中保持在核心庫,而將其他功能如路由和全局狀態管理交給相關的庫。此示例使用類似的語法,稱為。執行更快,因為它在編譯為代碼后進行了優化。基于的模板使得將已有的應用逐步遷移到更為容易。 前言 因為沒有明確的界定,這里不討論正確與否,只表達個人對前端MV*架構模式理解看法,再比較React和Vue兩種框架不同.寫完之后我知道這文章好水,特別是框架對比部分都是別人說爛的,而我也是打算把...
摘要:在模式中一般把層算在層中,只有在理想的雙向綁定模式下,才會完全的消失。層將通過特定的展示出來,并在控件上綁定視圖交互事件,一般由框架自動生成在瀏覽器中。三大框架的異同三大框架都是數據驅動型的框架及是雙向數據綁定是單向數據綁定。 MVVM相關概念 1) MVVM典型特點是有四個概念:Model、View、ViewModel、綁定器。MVVM可以是單向綁定也可以是雙向綁定甚至是不綁...
閱讀 2548·2023-04-25 19:47
閱讀 3388·2019-08-29 17:18
閱讀 858·2019-08-29 15:26
閱讀 3364·2019-08-29 14:17
閱讀 1128·2019-08-26 13:49
閱讀 3342·2019-08-26 13:22
閱讀 3027·2019-08-26 10:44
閱讀 2699·2019-08-23 16:51