摘要:增強(qiáng)除了解決復(fù)用問(wèn)題,高階的另一個(gè)重要作用就是對(duì)原始的進(jìn)行增強(qiáng)。就是典型的利用高階來(lái)增強(qiáng)的例子,它主要作用是使任意變成可以執(zhí)行撤銷(xiāo)和重做的全新。
在Redux架構(gòu)中,reducer是一個(gè)純函數(shù),它的職責(zé)是根據(jù)previousState和action計(jì)算出新的state。在復(fù)雜應(yīng)用中,Redux提供的combineReducers讓我們可以把頂層的reducer拆分成多個(gè)小的reducer,分別獨(dú)立地操作state樹(shù)的不同部分。而在一個(gè)應(yīng)用中,很多小粒度的reducer往往有很多重復(fù)的邏輯,那么對(duì)于這些reducer,如何抽取公共邏輯,減少代碼冗余呢?這種情況下,使用高階reducer是一種較好的解決方案
reducer復(fù)用
我們將頂層的reduce拆分成多個(gè)小的reducer,肯定會(huì)碰到reducer復(fù)用問(wèn)題。例如有A和B兩個(gè)模塊,它們的UI部分相似,此時(shí)可以通過(guò)配置不同的props來(lái)區(qū)別它們。那么這種情況下,A和B模塊能不能共用一個(gè)reducer呢?答案是否定的。我們先來(lái)看一個(gè)簡(jiǎn)單reducer:
const LOAD_DATA = "LOAD_DATA"; const initialState = { ... }; function loadData() { return { type: LOAD_DATA, ... }; } function reducer(state = initialState, action) { switch(action.type) { case LOAD_DATA: return { ...state, data: action.payload }; default: return state; } }
如果我們將這個(gè)reducer綁定到A和B兩個(gè)不同模塊,造成的問(wèn)題將會(huì)是,當(dāng)A模塊調(diào)用loadData來(lái)分發(fā)相應(yīng)的action時(shí),A和B的reducer都會(huì)處理這個(gè)action,然后A和B的內(nèi)容就完全一致了。
這里我們必需意識(shí)到,在一個(gè)應(yīng)用中,不同模塊間的actionType必須是全局唯一的。
因此,要解決actionType唯一的問(wèn)題,還有一個(gè)方法就是通過(guò)添加前綴的方式來(lái)做到:
function generateReducer(prefix, state) { const LOAD_DATA = prefix + "LOAD_DATA"; const initialState = { ...state, ...}; return function reducer(state = initialState, action) { switch(action.type) { case LOAD_DATA: return { ...state, data: action.payload }; default: return state; } } }
這樣只要A和B模塊分別調(diào)用generateReducer來(lái)生成相應(yīng)的reducer,就能解決reducer復(fù)用的問(wèn)題了。而對(duì)于prefix,我們可以根據(jù)自己的項(xiàng)目結(jié)構(gòu)來(lái)決定,例如${頁(yè)面名稱(chēng)}_${模塊名稱(chēng)}。只要能夠保證全局唯一性,就可以寫(xiě)成一種前綴。
reducer增強(qiáng)
除了解決復(fù)用問(wèn)題,高階reducer的另一個(gè)重要作用就是對(duì)原始的reducer進(jìn)行增強(qiáng)。redux-undo就是典型的利用高階reducer來(lái)增強(qiáng)reducer的例子,它主要作用是使任意reducer變成可以執(zhí)行撤銷(xiāo)和重做的全新reducer。我們來(lái)看看它的核心代碼實(shí)現(xiàn):
function undoable(reducer) { const initialState = { // 記錄過(guò)去的state past: [], // 以一個(gè)空的action調(diào)用reducer來(lái)產(chǎn)生當(dāng)前值的初始值 present: reducer(undefined, {}), // 記錄后續(xù)的state future: [] }; return function(state = initialState, action) { const { past, present, future } = state; switch(action.type) { case "@@redux-undo/UNDO": const previous = past[past.length - 1]; const newPast = past.slice(0, past.length - 1); return { past: newPast, present: previous, future: [ present, ...future ] }; case "@@redux-undo/REDO": const next = future[0]; const newFuture = future.slice(1); return { past: [ ...past, present ], present: next, future: newFuture }; default: // 將其他action委托給原始的reducer處理 const newPresent = reducer(present, action); if(present === newPresent) { return state; } return { past: [ ...past, present ], present: newPresent, future: [] }; } }; }
有了這高階reducer,就可以對(duì)任意一個(gè)reducer進(jìn)行封裝:
import { createStore } from "redux"; function todos(state = [], action) { switch(action.type) { case: "ADD_TODO": // ... } } const undoableTodos = undoable(todos); const store = createStore(undoableTodos); store.dispatch({ type: "ADD_TODO", text: "Use Redux" }); store.dispatch({ type: "ADD_TODO", text: "Implement Undo" }); store.dispatch({ type: "@@redux-undo/UNDO" });
查看高階reducer undoable的實(shí)現(xiàn)代碼可以發(fā)現(xiàn),高階reducer主要通過(guò)下面3點(diǎn)來(lái)增強(qiáng)reducer:
能夠處理額外的action;
能夠維護(hù)更多的state;
將不能處理的action委托給原始reducer處理。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/105567.html
摘要:事件系統(tǒng)合成事件的綁定方式合成事件的實(shí)現(xiàn)機(jī)制事件委派和自動(dòng)綁定。高階組件如果已經(jīng)理解高階函數(shù),那么理解高階組件也很容易的。例如我們常見(jiàn)的方法等都是高階函數(shù)。對(duì)測(cè)試群眾來(lái)說(shuō),從質(zhì)量保證的角度出發(fā),單元測(cè)試覆蓋率是 事件系統(tǒng) 合成事件的綁定方式 `Test` 合成事件的實(shí)現(xiàn)機(jī)制:事件委派和自動(dòng)綁定。 React合成事件系統(tǒng)的委托機(jī)制,在合成事件內(nèi)部?jī)H僅是對(duì)最外層的容器進(jìn)行了綁定,并且依賴(lài)...
摘要:學(xué)習(xí)之道簡(jiǎn)體中文版通往實(shí)戰(zhàn)大師之旅掌握最簡(jiǎn)單,且最實(shí)用的教程。前言學(xué)習(xí)之道這本書(shū)使用路線圖中的精華部分用于傳授,并將其融入一個(gè)獨(dú)具吸引力的真實(shí)世界的具體代碼實(shí)現(xiàn)。完美展現(xiàn)了的優(yōu)雅。膜拜的學(xué)習(xí)之道是必讀的一本書(shū)。 《React 學(xué)習(xí)之道》The Road to learn React (簡(jiǎn)體中文版) 通往 React 實(shí)戰(zhàn)大師之旅:掌握 React 最簡(jiǎn)單,且最實(shí)用的教程。 showIm...
摘要:作為大型應(yīng)用狀態(tài)管理最常用的工具。它是一個(gè)應(yīng)用數(shù)據(jù)流框架,與框架類(lèi)似。這是觸發(fā)變化的惟一途徑。在這個(gè)函數(shù)內(nèi)部,被調(diào)用,其作用是監(jiān)測(cè)是的。否則的話,認(rèn)為只是一個(gè)普通的,將通過(guò)也就是進(jìn)一步分發(fā)。到此源碼的主要部分學(xué)習(xí)結(jié)束。 Redux作為大型React應(yīng)用狀態(tài)管理最常用的工具。它是一個(gè)應(yīng)用數(shù)據(jù)流框架,與Flux框架類(lèi)似。它是零依賴(lài)的,可以配合其他框架或者類(lèi)庫(kù)一起使用。雖然在平時(shí)的工作中很多...
摘要:希望大家在這浮夸的前端圈里,保持冷靜,堅(jiān)持每天花分鐘來(lái)學(xué)習(xí)與思考。 今天的React題沒(méi)有太多的故事…… 半個(gè)月前出了248個(gè)Vue的知識(shí)點(diǎn),受到很多朋友的關(guān)注,都強(qiáng)烈要求再出多些React相前的面試題,受到大家的邀請(qǐng),我又找了20多個(gè)React的使用者,他們給出了328道React的面試題,由我整理好發(fā)給大家,同時(shí)發(fā)布在了前端面試每日3+1的React專(zhuān)題,希望對(duì)大家有所幫助,同時(shí)大...
摘要:在前端基礎(chǔ)進(jìn)階八深入詳解函數(shù)的柯里化一文中,我有分享柯里化相關(guān)的知識(shí)。雖然說(shuō)高階組件與柯里化都屬于比較難以理解的知識(shí)點(diǎn),但是他們組合在一起使用時(shí)并沒(méi)有新增更多的難點(diǎn)。 可能看過(guò)我以前文章的同學(xué)應(yīng)該會(huì)猜得到當(dāng)我用New的方法來(lái)舉例學(xué)習(xí)高階組件時(shí),接下來(lái)要分享的就是柯里化了。高階組件與函數(shù)柯里化的運(yùn)用是非常能夠提高代碼逼格的技巧,如果你有剩余的精力,完全可以花點(diǎn)時(shí)間學(xué)習(xí)一下。 在前端基礎(chǔ)進(jìn)...
閱讀 1233·2021-11-23 09:51
閱讀 678·2021-11-19 09:40
閱讀 1337·2021-10-11 10:58
閱讀 2347·2021-09-30 09:47
閱讀 3726·2021-09-22 15:55
閱讀 2160·2021-09-03 10:49
閱讀 1250·2021-09-03 10:33
閱讀 698·2019-08-29 17:12