if 讀完了 then 你能瞭解到:vue
- 好鋼用在刀刃 - redux的應用場景
- 萬變不離其宗 - redux的基本思路
最近有個任務,就是須要在一個開源項目上進行擴展開發,而這個開源項目用到的是很是主流的 react 和 react-redux,近些年一直在跟 vue 打交道(廣告植入:好比開源了一個 vue 版本的 ncform 項目),冷落了 react 有一段時間了,恰好趁機重溫下 react 及其周邊相關的技術生態java
react-redux,其實就是 redux 的 react 版本,方便 redux 在 react 中使用。react
而 redux,是 javaScript 應用狀態管理容器,是參考 flux 設計模式的一種實現(vue 的 vuex 也是相似的實現),它獨立於各類 web 框架但又可融入於各類 web 框架。git
不少人會認爲,引入 redux 會增長應用的複雜性。確實不簡單,但存在即合理,因此什麼場景下適合使用 redux 就很關鍵了。github
我就開發一個活動頁。奉勸你不要用 redux 啦,一點好處都沒有,只會增長複雜性。web
切記:不要爲了用而用 - 然而現實中這種現象是大量存在的vuex
當一個應用的功能愈來愈多時,開始進行功能模塊拆分,這個時候,就會遇到一個問題,功能模塊之間共享的數據如何處理,好比登陸用戶的信息。redux
例子能再具體點嗎?好吧,但仍是登陸用戶信息,哈哈。設計模式
好比你在用戶模塊修改了頭像,而後頂欄上的登陸頭像要實時跟着更新,這個時候,實際上是用戶模塊和頂欄共享了你的用戶頭像信息api
解決這種可能有N種方法,今天既然聊 redux,那就專心講它吧
當你把數據梳理一下,你會發現有些數據是在模塊內共享的,有些數據是在模塊間共享的,咱們將在模塊間共享的稱之爲應用級別的數據,即 Application 級別,redux 就是專門處理這種級別數據的解決方案
咱們用 redux 官方的 todo app 例子來說解( Warning: 僅爲了說得簡單,講得明白,這種小應用是不適合引入 redux 的 )
你的應用有着一份描述着狀態(state)的數據,可能以下:
🔸 術語
State: 應用級別的狀態數據
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}],
visibilityFilter: 'SHOW_COMPLETED'
}
複製代碼
這份 state 是靜態的,你能夠理解爲就是應用最初的狀態。
當我完成了 Exercise
項,我就打個勾,表示我完成了。此時就須要更改下應用的狀態,須要把 Exercise
那一項 的completed
由 false 改爲 true。
怎麼更改呢?直接把值改了不就完事了?
若是直接改變 state 對象的屬性值,就斷了 state 更改的軌跡,簡單講就是你修改了一個對象的屬性值,你就很難追蹤屬性值更改前是什麼樣子了。這在調試排查問題的時候很是有用。
必定有更好的方法,可參考下事件的機制。因此當想更改狀態時,咱們派發(dispath)一個操做(action),描述清楚咱們想幹什麼,而不是直接就幹了。一個操做的描述可能以下:
{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }
複製代碼
🔸 術語
dispatch: 經過該方法主動派發操做
action: 描述操做的內容,type
值必須提供,指定行爲的類型,至關於事件的名稱
用派發操做的好處:
將每一個更改描述爲一個操做,讓咱們清楚地瞭解應用程序中發生的狀況。 若是發生了變化,咱們就知道它爲何會改變,操做就像麪包屑,使得應用狀態的變化有跡可循
OK,至此啥事還沒作,只是嘴上嚷嚷我要作什麼,那總得有實際處理的方法吧。
沒錯,這些實際修改狀態的方法稱爲 reducer。實現可能以下:
function visibilityFilter(state = 'SHOW_ALL', action) {
if (action.type === 'SET_VISIBILITY_FILTER') {
return action.filter
} else {
return state
}
}
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([{ text: action.text, completed: false }])
default:
return state
}
}
複製代碼
🔸 術語
reducer:它負責接收當前 state 和 action,而後按照 action 的 type,根據當前 state 進行操做,最終返回一個全新的 state(返回全新的 state 保證了 數據修改的可追溯性)。
你會發現 visibilityFilter
返回的是查詢條件字符串,而 todos
返回的是列表項數組列表。把它們返回的數據合併起來,就是一個完整的應用狀態,以下:
function todoApp(state = {}, action) {
return {
todos: todos(state.todos, action),
visibilityFilter: visibilityFilter(state.visibilityFilter, action)
}
}
複製代碼
OK,到此爲此,想幹什麼也說了,實際作事的也講了,但好像仍是雲裏霧裏,腦殼裏依然沒有很清晰的全局的畫面,好像還少了什麼東西。
告訴你,少了一個管家,它管着應用的狀態,它就是 store。
🔸 術語
Store: 管理應用狀態數據,負責把 action, reducer 等串起來
咱們借用 redux 的一些 api 來完整描述一個數據修改的全過程
let store = createStore(todoApp)
複製代碼
function listener() { console.log(store.getState()) }
store.subscribe(listener)
複製代碼
let action = { type: 'ADD_TODO', text: 'Go to swimming pool' }
store.dispatch(action)
複製代碼
😫修改了好屢次,終於寫完了。。。
接下來的內容跟本文一毛錢關係都沒,只是一如既往地打一波廣告:
ncform,一種使人愉悅的表單開發方式,僅需配置便可生成表單UI及其交互行爲。
自帶豐富的 標準組件 和 校驗規則,開箱即用。
具有強大的 控件交互 和 擴展能力,作你所想。
github: github.com/ncform/ncfo…
注:目前只有 vue 版本,但願在不久的未來,有時間發佈 react 版本
tags: react, flux, react-redux, redux