[轉]Redux 介紹

轉自:https://segmentfault.com/a/1190000003503338?_ea=323420

本文主要是對 Redux 官方文檔 的梳理以及自身對 Redux 的理解。

單頁面應用的痛點
對于復雜的單頁面應用,狀態(state)管理非常重要。state 可能包括:服務端的響應數據、本地對響應數據的緩存、本地創建的數據(比如,表單數據)以及一些 UI 的狀態信息(比如,路由、選中的 tab、是否顯示下拉列表、頁碼控制等等)。如果 state 變化不可預測,就會難于調試(state 不易重現,很難復現一些 bug)和不易于擴展(比如,優化更新渲染、服務端渲染、路由切換時獲取數據等等)。
Redux 就是用來確保 state 變化的可預測性,主要的約束有:
state 以單一對象存儲在 store 對象中

state 只讀

使用純函數 reducer 執行 state 更新

state 為單一對象,使得 Redux 只需要維護一棵狀態樹,服務端很容易初始化狀態,易于服務器渲染。state 只能通過 dispatch(action) 來觸發更新,更新邏輯由 reducer 來執行。

Actions、Reducers 和 Store
action 可以理解為應用向 store 傳遞的數據信息(一般為用戶交互信息)。在實際應用中,傳遞的信息可以約定一個固定的數據格式,比如: Flux Standard Action。 為了便于測試和易于擴展,Redux 引入了 Action Creator:
function addTodo(text) { return { type: ADD_TODO, text, }}store.dispatch(addTodo(text))

dispatch(action) 是一個同步的過程:執行 reducer 更新 state -> 調用 store 的監聽處理函數。如果需要在 dispatch 時執行一些異步操作(fetch action data),可以通過引入 Middleware 解決。

reducer 實際上就是一個函數:(previousState, action) => newState
。用來執行根據指定 action 來更新 state 的邏輯。通過 combineReducers(reducers) 可以把多個 reducer 合并成一個 root reducer。
reducer 不存儲 state, reducer 函數邏輯中不應該直接改變 state 對象, 而是返回新的 state 對象(可以考慮使用 immutable-js)。

store 是一個單一對象:
管理應用的 state

通過 store.getState()
可以獲取 state

通過 store.dispatch(action)
來觸發 state 更新

通過 store.subscribe(listener)
來注冊 state 變化監聽器

通過 createStore(reducer, [initialState])
創建

在 Redux 應用中,只允許有一個 store 對象,可以通過 combineReducers(reducers) 來實現對 state 管理的邏輯劃分(多個 reducer)。

Middleware
middleware 其實就是高階函數,作用于 dispatch 返回一個新的 dispatch(附加了該中間件功能)。可以形式化為:newDispatch = middleware1(middleware2(...(dispatch)...))

// thunk-middlewareexport default function thunkMiddleware({ dispatch, getState }) { return next => action => typeof action === 'function' ? action(dispatch, getState) : next(action)}

通過 thunk-middleware 我們可以看出中間件的一般形式:中間件函數接受兩個參數參數: dispatch 和 getState(也就是說中間件可以獲取 state 以及 dispatch new action
)。中間件一般返回 next(action)
(thunk-middleware 比較特殊,它用于 dispatch 執行異步回調的 action)。store 的創建過程如下:
const reducer = combineReducers(reducers)const finalCreateStore = applyMiddleware(promiseMiddleware, warningMiddleware, loggerMiddleWare)(createStore)const store = finalCreateStore(reducer)

異步 Actions
單頁面應用中充斥著大量的異步請求(ajax)。dispatch(action) 是同步的,如果要處理異步 action,需要使用一些中間件。 redux-thunksredux-promise 分別是使用異步回調和 Promise 來解決異步 action 問題的。
Redux 和傳統 Flux 框架的比較


圖來自 UNIDIRECTIONAL USER INTERFACE ARCHITECTURES
Redux 和 React
Redux 和 React 是沒有必然關系的,Redux 用于管理 state,與具體的 View 框架無關。不過,Redux 特別適合那些 state => UI
的框架(比如:React, Deku)。
可以使用 react-redux 來綁定 React,react-redux
綁定的組件我們一般稱之為 smart components
Smart and Dumb Components 在 react-redux
中區分如下:

Location
Use React-Redux
To read data, they
To change data, they

“Smart” Components
Top level, route handlers
Yes
Subscribe to Redux state
Dispatch Redux actions

“Dumb” Components
Middle and leaf components
No
Read data from props
Invoke callbacks from props

簡單來看:Smart component` 是連接 Redux 的組件(@connect),一般不可復用。Dumb component 是純粹的組件,一般可復用。兩者的共同點是:無狀態,或者說狀態提取到上層,統一由 redux 的 store 來管理。redux state -> Smart component -> Dumb component -> Dumb component(通過 props 傳遞)。在實踐中,少量 Dumb component 允許自帶 UI 狀態信息(組件 unmount 后,不需要保留 UI 狀態)。值得注意的是,Smart component 是應用更新狀態的最小單元。實踐中,可以將 route handlers 作為 Smart component,一個 Smart component 對應一個 reducer。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容