深入Redux
簡述
在快速理解redux中,我簡單的介紹了redux的基礎內容,本篇文章中,我們將再度深入redux。
redux解決的問題
- 數據和函數的層層傳遞
- 多個組件同時修改某全局變量
一、react數據流
- 衆所周知,react的單向數據流是這樣的,父組件可以向子組件傳遞數據
我們通常用過狀態提升將數據存於高階函數中,使我們的子組件儘可能的更"純",更好的實現代碼複用。 - 可能在頁面結構簡單的小型項目中我們還沒覺得有什麼不妥,但是倘若在頁面結構稍複雜的項目中,就會變成這樣
D組件中的數據存於Container中,要通過Container -> Content -> B -> D
才能到達D組件。
當然,這對我們聰明有能幹的開發者們並不算什麼,耗些時間也能剛出來。 - Then,這種頁面,你還能搞得定嗎?
就算你能搞定,你的代碼中也有大量的冗餘,從Container到N之間的所有組件都要傳遞N需要的props - 所以,爲了解決層層傳遞,react-redux就出現了
它利用了react中的context,在Container的context裏創建store,使Container的所有子組件,孫組件等等都可以直接獲取store中的內容。
二、修改store
我曾在快速理解redux中提起,爲了解決模塊(組件)之間需要共享數據 和 數據可能被任意修改導致不可預料的結果 的矛盾,redux團隊創建了dispatch
。So 不可預料的結果究竟是什麼?
我們思考一個問題,假如所有的組件都以 store.xxx = xxx; // 僞代碼
這種方式修改全局變量,會引發什麼問題?
我們再思考,爲何python等語言會存在線程鎖,數據庫也存在鎖,操作系統的生產者/消費者問題等等
假如A和B同時修改store,store是遵從A還是遵從B?
爲了避免以上情況引發死鎖redux想出了一個辦法:封裝一個dispatch函數,接收一個action對象作爲參數,每當組件想要修改store時必須給dispatch傳遞action,然後再store內部根據action對象的type將dispatch分發到相應的隊列中,每一時刻僅執行一個dispatch
三、redux異步問題
思考這樣一個情景,我們從後端的接口獲取了數據,我們想將其存入store中。但是當執行到reducer時,數據是否已經獲取到?假如沒有,又該怎麼辦?
就在此時,中間件出現了,例如 redux-saga, redux-thunk 等等。
-
redux-saga 使用了generate生成器,使開發者可以按同步思路的書寫異步代碼,再根據action的type選擇相應reducer更新store
function *fetchNodeDetailByNodeId({ payload: { nodeId } }, { call, put }) { try { const { data, status }= yield call(fetchNodeDetailByNodeId, nodeId) if (data && status.errmsg === 'success') { yield put({ type: 'setStates', payload: { nodeDetailData: data, }, }); } else { message.info('開了個小差,再試一次吧..'); } } catch (error) { console.log(error); } },