知乎:
對於大型複雜應用程式來說,我們經常需要共享某些元件的狀態或者乙個元件需要改變另外乙個元件的狀態。 如果沒有乙個合適的管理工具管理狀態,很快就會變成一團亂。使用 redux 的開發者越來越多,但背後 redux 原理和為什麼用 redux 很多人其實並不清楚。如果我們不能完全理解 redux 的思想,可能在實際的應用中,會盲目使用。本文主要結合 redux 原始碼分析 redux 原理,幫忙大家更好的使用 redux。
store 在中文裡是儲備的意思,store 其實就是乙個儲存資料的倉庫,按照 redux 設計理念,store 只能有乙個。下面是經過簡化的 createstore 原始碼,方便大家理解。
// reducer 是純函式
export default function createstore(reducer)
/*** 用來觸發狀態改變
** @param action
** @returns 原來action
*/function dispatch(action)
// 初始化 state tree.
dispatch()
return
}複製**
store 是乙個由 createstore 函式建立生成的物件,包括了 dispatch, subscribe, getstate等屬性。createstore 第乙個引數是純函式 reducer,經過 dispatch 初始化,呼叫 reducer 函式生成了新的 state。
store 包括了所有的資料,如果要得到某個時點的資料,就要對 store 生成快照。這個時點的資料集合,就叫 state。根據上文的原始碼,我們知道通過呼叫 store.getstate() 就能獲取到當前的 state 物件。
使用者不能修改 view, 不能直接修改 state,於是就有了 action 的概念。action 是乙個物件,其中 type 屬性是必須的。
/**
* 用來觸發狀態改變
** @param action
** @returns 原來action
*/function dispatch(action)
複製**
dispatch(action) 後,會呼叫當前的 reducer 根據 state 和 action ,生成新的 state;
如果每乙個action都需要手寫,會非常麻煩,可以定義乙個函式生成 action,這個函式就叫 action creator,下面是用法示例。
const add_todo = '新增 todo';
function addtodo(text)
}const action = addtodo('learn redux');
複製**
這個函式作用是簡化 store.dispatch 呼叫, 將乙個或一組actioncreator跟 dispatch 繫結
//將dispatch 繫結到 actioncreator
function
bindactioncreator(actioncreator, dispatch)
export default function
bindactioncreators(actioncreators, dispatch)
if (typeof actioncreators !== 'object' || actioncreators === null) . ` +
`did you write "import actioncreators from" instead of "import * as actioncreators from"?`
)} const keys = object.keys(actioncreators)
const boundactioncreators = {}
// 遍歷物件,然後對每個遍歷項的 actioncreator 生成函式,將函式按照原來的 key 值放到乙個物件中,最後返回這個物件
for (let i = 0; i < keys.length; i++) else ', instead received type
'$'.`)
}} return boundactioncreators
}複製**
定義了 action,那麼如何執行 action呢?dispatch 是 redux 執行 action 唯一方法。下面是 dispatch 函式全部原始碼,整個邏輯非常簡單。使用 reducer 函式處理當前 state,處理完成後,執行訂閱的 listeners。
function dispatch(action)
//檢查action.type是否定義
if (typeof action.type === 'undefined')
//如果正在dispath,丟擲錯誤
if (isdispatching)
try finally
//將下乙個***傳給當前***,使用for迴圈依次執行listener
const listeners = currentlisteners = nextlisteners
for (let i = 0; i < listeners.length; i++)
return action
}複製**
store 收到 action 之後,需要計算乙個新的 action, 這種計算 state 變化的函式,就叫 reducer。
const chatreducer = (state = defaultstate, action = {}) => = action;
switch (type) , state, );
case change_status:
return object.assign({}, state, );
case change_username:
return object.assign({}, state, );
default: return state;
}};複製**
乙個大型應用是由很多元件組成的,如果全部寫到乙個 reducers 方法,不易維護。通過 redux 提供的 combinereducers 方法可以將多個 reducers 合併成乙個 reducers。
/**
* 這個函式可以組合一組 reducers(物件) ,然後返回乙個新的 reducer 函式給 createstore 使用。
* * @param reducers reducers 組成的物件
* * @returns 返回乙個組合後的reducer .
*/export default function combinereducers(reducers)
for (let i = 0; i < reducerkeys.length; i++)
} const finalreducerkeys = object.keys(finalreducers)
//返回新合併的reducer
return
function combination(state = {}, action)
//用for迴圈遍歷,根據key取出的reducer和舊的state,然後執行reduder函式獲取新的state。如果state有變化,返回新的state
for (let i = 0; i < finalreducerkeys.length; i++)
return haschanged ? nextstate : state
}}複製**
《大道至簡》之溝通
c語言是每個程式設計師必需學習的語言,也是必須要掌握的語言。它對於開發人員,卻不一定對每乙個人來說重要。客戶是不需要掌握 c語言的,在開發人員看來,他們希望客戶學習或精通 c語言,這樣可以方便他們之間交流和溝通,可是要求客戶學習 c語言明顯是自殺式的行為。所以,開發人員最還不要只見面對客戶,讓專案經...
看了《大道至簡》
無意間在網上翻到這本書,粗粗的看了一遍,有點感觸。可以研究細節,但不能陷入,可以一時陷入,但不能一世陷入。當然,這對技術狂熱者或許是除外的。如果要解決問題,那麼無論何種程式語言,都是一種工具,要做的是對於當前的問題選擇適合的工具。任何一種工具都是在某個情境下才可以區分孰優孰劣。中國的一些理論,很少放...
讀大道至簡
軟體開發 方法 過程 工程 組織 演算法 結構 方法 面向過程 物件導向 過程 瀑布模型 迭代模型 工程 專案管理 進度 成本 質量 組織 體制 組織結構和制度 是乙個向外擴充套件的過程。方法 分,模組化設計 過程 增量迭代,還是瀑布模型 工程 進度 成本 質量 組織 組織結構 制度 舉乙個做生意的...