摘要:而不是卷入無休止的撕逼,用了某某而產生的優越,甚至借貶低他人來抬高自己。
前言
?這是一個系列文章,旨在分享在react及相關技術棧實踐過程中的個人感悟,心得。如果有不好的地方,歡迎各位批評指正。
?由于對react本身還未深入了解,今天我們先來談一談redux相關的問題。
Who creates it??Dan Abramov是redux的作者,同時,他也是Create React App, React Hot Loader作者。當然1年前,他也由于redux及相關的開源貢獻加入了facebook(他大二就輟學了,之前還當過.net工程師)。
?在我最初了解到他的時候,我覺得他非常有禮貌。同時,也為了更多的了解redux,我計劃開始閱讀他的每一條tweet,原先計劃的是從15年7月開始,后來因為進展緩慢,而且react版本也已經發生很大變化了,于是便從16年1月1日開始閱讀,目前記錄到7月15日了。事實也證明,在這個過程中,的的確確學習到了很多東西。包括redux的文檔及redux-links的作者Mark Erikson,以及國外很多寫過redux系列的朋友們。
?如果你有興趣的話,可以看看我摘錄的一些片段。其中除了知識性的內容外,還有一些關于它自己生活,經歷,學習方法,如何面對JS疲勞等等的摘錄。也讓我漸漸的了解到了國外的程序員們的一些觀點,興趣,梗等等。
正文?好了,暫時先介紹到這里了。切回redux本身,下面是學習源碼過程中自己的一些體會。
createStore?createStore的第3個參數為enhancer,如果enhancer有多個,那么應該使用compose的方式組合多個enhancer
?且每個enhancer的模板為export default createStore => (reducer, preloadedState, enhancer) => {...}
?因為在createStore中執行了:return enhancer(createStore)(reducer, preloadedState)
?另外,上面的提到的形如(reducer, preloadedState, enhancer) => {...} 這個樣子的其實都可以叫做createStore
?這也是社區有那么多enhancer的原因,他們可以形成一個enhancer鏈,我調用你的createStore,然后返回我的createStore供下一級調用
?所以在自己的createStore的函數體中經常能看到諸如var store = createStore(reducer, preloadedState, enhancer);這樣的用法,目的就是讓自己這一級之前的enhancer產生一個store出來,而之前的enhancer里的createStore又會調用之前的,到最盡頭,就是redux本身的createStore
applyMiddleware?applyMiddleware的目的是返回一個enhancer,這個enhancer存儲了1個或者多個中間件,中間件在上一級的dispatch方法的基礎上增添自己的邏輯,然后返回自己的dispatch方法
?對于中間件而言,中間件的模板為:export default store => next => action => {...}。有的地方也寫成export default _ref => next => action => {...}或者export default ({getState, dispatch}) => next => action => {...},看自己喜好了
?實際的調用順序如下(定義在redux的applyMiddleware.js中):
1. middleware(middlewareAPI); /* var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) }; chain = middlewares.map(middleware => middleware(middlewareAPI)); dispatch = compose(...chain)(store.dispatch); 第1步即為第1次執行中間件,用redux自己的dipatch初始化各個中間件里的dispatch(也就是中間件的next參數)和getState。 從而確保至少redux本身能夠正常工作,中間件的store或者_ref即為這里的middlewareAPI * */ 2. dispatch = compose(...chain)(store.dispatch); /* 第2步即為第2次執行中間件 即用compose的形式鏈式調用第1步返回的中間件集合,如果中間件是定義在applyMiddleware的最后一個 那么中間件里的next為store.dispatch,否則next為上一個中間件返回的結果,可以理解為上一個中間件 返回的是封裝了dispatch的自己的dispatch,這里的原理其實和enhancer一模一樣 enhancer的目的是封裝多次createStore并用compose的方式進行調用 middleware的目的是封裝多次dispatch并用compose的方式進行調用 * */ 總結: /* 所以最后在redux的createStore.js中return的enhancer(createStore)(reducer, preloadedState)的結果就是一個增強 版的store,而這個增強版的store中存放的是增強版的dispatch * */ /* ××××××××××××××××關于combineReducers××××××××××××××× * 從執行上來說,combineReducers實際上最后就是變成對reducers進行深度優先遍歷并執行的過程 * 從結構上來說,combineReducers決定了我們的state狀態樹的最終結構或者說形狀,他是呈一個樹型結構的 * combineReducers(reducerA, reducerB),reducerA里面嵌套combineReducers(reducerA-child1, reducerA-child2) * 實際上對應狀態樹而已就是第一層有兩個節點A,B,而A節點下面有兩個子節點A-child1,A-child2 * * 所以在最初設計的時候,我們要設想我們最終的狀態樹的樣子,然后合理劃分reducer,就像設計數據庫的表結構一樣。 當然這是比較概括的說法,事實上reducer的設計或者說state的劃分有太多太多值得研究的東西,這個我們以后再談了。 * */bindActionCreator
bindActionCreator實際就是給actionCreator外層再添加了一層函數,而這層函數存放了對dispatch的引用
function bindActionCreator(actionCreator, dispatch) { return (...args) => dispatch(actionCreator(...args)) }
所以我們可以一般在組件里直接調用bindActionCreator返回的actionCreator,即this.props.loadSomething(...)。而不用寫成dispatch(actionCreator(...args)),實際上他們是等價的
connect?既然提到了redux,由于目前我是采用react進行開發,所以不得不提到相關的react-redux。其中最重要的莫屬于connect這個函數了。
?傳入connect的組件在掛載到頁面上后會調用store.subscribe進行訂閱,訂閱的目的是我們調用dispatch的時候,表明我們的狀態樹即將發生變化,這個時候我們希望我們的組件對應發生變化,而組件變化的唯一方式就是setState。
?訂閱就是告訴redux,這個組件是依賴于狀態樹的某部分工作的,所以當你變化的時候,記得獲取最新的state,然后通知我,至于我如何響應,那就是我自己的事了,你只管通知我狀態樹發生了變化并把它傳給我就行了。值得一提的是,connect內部進行了大量的性能優化,避免不必要的渲染,關于此以及mapStateToProps和mapDispathToProps,我們放到以后再談。
結語?篇幅有限,這一篇文章暫時就先這樣啦,更多的內容,我想放在下一篇來分享,同時自己也在不斷學習,希望能理解得更好。
?值得一提的是,我們也許會認為我們了解到的redux,mobx,rxjs等等完全不同理念的庫,他們的作者也許也是"極端"的,是排斥他人及理念的。實際上,這是不正確的,早在16年5月,Dan就和mobx的作者在twitter上有過互動,他們達成了共識,那就是和對方一起合作,一起推動自身以及react的發展。
?對于redux-thunk,文檔中也許會首先建議使用這個簡單的庫來處理異步相關的問題。對于復雜的應用,他們也推薦使用redux-saga這樣的庫去重構自己的代碼。在twitter上,Dan也多次提到過庫的應用場景的問題,建議大家用之前先了解自己為什么要使用,它解決了哪些痛點,然后再去使用。甚至特意提過issue,來了解react-router-redux的作用。
?除此之外,也提到在時間充裕的情況下,學習react,應該先從本身入手,ES6,webpack,jsx,redux等等和react本身都是沒有直接聯系的,在學習完react之后,我們知道了他本身的哪些不足,哪些地方需要加強,哪些地方需要引入第三方庫去解決,解決的是哪些痛點,我們再去了解這些工具,才能真正體會到他們的威力。
?說到這里,稍微有一點遠了,不過我覺得還是有必要提及一下。那就是,我們身處一個浮躁的社會,無論是在現實中對待朋友,親人,陌生人,由于學習,工作,生活的壓力,周遭的浮躁氛圍的影響,多多少少也會讓自己帶著些許暴戾之氣。在網絡上,由于約束的放寬,我們也許更會將壓抑的情感釋放給廣袤的網絡世界,在微博,貼吧,知乎上,我們或多或少書寫著,察覺著這樣的行為。
?但是,作為一名程序猿,我還是期待能夠看到我們這個圈子更多的將時間,精力,努力花費在對現有技術的改進,對未知世界的探索,追尋程序,庫,框架,思想的本質,結交志同道合的朋友,一起交流,分享,思考對技術的看法。而不是卷入無休止的撕逼,用了某某而產生的優越,甚至借貶低他人來抬高自己。
?我們可以理解一時的憤懣之情,因為我們大多,真是只是普普通通的社會人,喜怒哀樂再平常不過。但若我們一直保持這種狀態,永遠在上面這些場景都留下對人不對事的話語,譏諷,甚至謾罵。希望大家能為我們的后代想想。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81288.html
摘要:因為是想搭建一個后臺系統,所以組件直接定了,腳手架以為基準,加上和因為我一直用的這次換個口味搭建一個簡單的項目。 因為是想搭建一個后臺系統,所以組件直接定了antd,腳手架以create-react-app為基準,加上redux和sass(因為我一直用的less,這次換個口味),搭建一個簡單的項目。 安裝依賴 首先安裝create-react-app npm i create-reac...
摘要:只有在你需要實現代碼分隔,而且需要立即加載一些的時候才可能會用到它。 import isPlainObject from lodash/isPlainObject import $$observable from symbol-observable /** * These are private action types reserved by Redux. * For any ...
摘要:函數用于為應用的狀態添加監聽,以一個回調函數監聽函數為參數當觸發時執行所有監聽函數,返回能夠取消訂閱的函數。函數用于組合多個中間件返回的函數,其實質是生成新的暴露給用戶。 redux 源碼閱讀筆記 redux 中的 reducer 為什么要叫這個名字?(UPDATED) 筆者在學習 redux 的時候一直感覺 reducer 很不好理解(非要進行翻譯的話,可以稱之為縮減器/折疊器),而...
摘要:大家好,今天給大家帶來的是的源碼分析首先是的地址點我接下來我們看看在項目中的簡單使用,一般我們都從最簡單的開始入手哈備注例子中結合的是進行使用,當然不僅僅能結合,還能結合市面上其他大多數的框架,這也是它比較流弊的地方首先是創建一個首先我們 大家好,今天給大家帶來的是redux(v3.6.0)的源碼分析~ 首先是redux的github地址 點我 接下來我們看看redux在項目中的簡單使...
閱讀 820·2021-10-25 09:48
閱讀 611·2021-08-23 09:45
閱讀 2496·2019-08-30 15:53
閱讀 1759·2019-08-30 12:45
閱讀 586·2019-08-29 17:21
閱讀 3407·2019-08-27 10:56
閱讀 2547·2019-08-26 13:48
閱讀 691·2019-08-26 12:24