Redux 介紹

Redux 介紹

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

單頁面應用的痛點

對於複雜的單頁面應用,狀態(state)管理很是重要。state 可能包括:服務端的響應數據、本地對響應數據的緩存、本地建立的數據(好比,表單數據)以及一些 UI 的狀態信息(好比,路由、選中的 tab、是否顯示下拉列表、頁碼控制等等)。若是 state 變化不可預測,就會難於調試(state 不易重現,很難復現一些 bug)和不易於擴展(好比,優化更新渲染、服務端渲染、路由切換時獲取數據等等)。react

Redux 就是用來確保 state 變化的可預測性,主要的約束有:git

  • state 以單一對象存儲在 store 對象中github

  • state 只讀ajax

  • 使用純函數 reducer 執行 state 更新redux

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

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-middleware
export 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 框架的比較

傳統 Flux 架構圖
Reudx 架構圖

圖來自 UNIDIRECTIONAL USER INTERFACE ARCHITECTURES

Redux 和 React

Redux 和 React 是沒有必然關係的,Redux 用於管理 state,與具體的 View 框架無關。不過,Redux 特別適合那些 state => UI 的框架(好比:React, Deku)。

能夠使用 react-redux 來綁定 React,react-redux 綁定的組件咱們通常稱之爲 smart componentsSmart and Dumb Componentsreact-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。

相關文章
相關標籤/搜索