iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Modern Web

開始搞懂React生態系系列 第 22

Day 22 Redux Middleware 基本運作原理

  • 分享至 

  • xImage
  •  

說明

Middleware 稱為中介層,在許多後端伺服器框架中都可以看到 Middleware 的應用,Middleware 會在定義好的起點與終點之間,針對中間的過程做處理。

Redux Middleware 則是在 Action 進入到 Reducer 之前,可以讓我們做一些介入 Action 的時間點,它在 dispatch action 和 action 到達 reducer 的時間點之間提供了一個第三方的擴充點。

在 React 中,可以擁有很多個 Middleware,每個 Middleware 會檢查自己份內要處理的 Action,無論有沒有處理都會傳給下一個串連的 Middleware 做處理。

透過 Redux Middleware,可以對 Action 做延遲、記錄、調整或停止的處理,實務上可用以做 Log 回報、執行非同步 API、Routing 等功能處理。

如何使用 Middleware

把一個或多個 Middleware 傳入 Redux 提供的 applyMiddleware 函式,再把 applyMiddleware 函式,傳入 createStore 的第二個參數即可。

import { createSotre, applyMiddleware} from 'redux';

const store = createStore(
  reducers,
  applyMiddleware(
    middlewareOne,
    middlewareTwo
  )
);

為了讓程式碼更好理解且增加彈性,也可用一個變數 enhancers 做為 applyMiddleware 函式的回傳。

import { createSotre, applyMiddleware} from 'redux';

const enhancers = applyMiddleware(middlewareOne, middlewareTwo);

const store = createStore(reducers, enhancers);

Middleware boilerplate

Middleware 的樣版長的像這樣:

function middleware(store) {
  return function(next) {
    return function(action) {
      /* Code */
      return next(action);
    };
  };
}

使用 ES6 Arrow Function 簡化後的寫法

const middleware = store => next => action => {
  /* Code */
  return next(action);
};

Middleware 的 next

next 是用來將 Action 交棒給下一個 Middleware 的處理的函式。

每一個 Middleware 接到的 Action 都會是前一個 Middleware 呼叫 next 傳入的 Action,如果沒有下一個 Middleware 就會交由 Reducer 處理。

用實例理解 Middleware

接下來會使用 Log 及當機回報做為範例,來深入探究 Middleware 的形成思考過程。

Logger Middleware

先套用 boilerplate 如下

const logger = store => next => action => {
  // do something
  return next(action);
};

製作一個 Logger Middleware,用來打印出每個 dispatch 的 action 及 action 之後的 state,當發生不符合預期結果時,可以檢查 log 找出是哪一個 action 破壞了 state。

const logger = store => next => action => {
  // 印出要做 dispatch 的 action
  console.log('dispatching', action);
  let result = next(action)
  // 印出 action 處理完的 new state
  console.log('next state', store.getState())
  return result;
};

crashReporter Middleware

當在 dispatch 一個 action 時,如果發生失敗時,可以把錯誤堆疊、導致錯誤的 action 和當下的 state 傳送到一個當機回報服務(範例使用 Raven.captureException ),協助在開發環境中重現錯誤。

const crashReporter = store => next => action => {
  try {
    return next(action);
  } catch (err) {
    console.error('Caught an exception!', err);
    /* 實務上可用的當機回報服務
    Raven.captureException(err, {
      extra: {
        action,
        state: store.getState()
      }
    });
    */
    throw err;
  }
};

組合 Middleware 且運用至 Redux Store

import {
  createSotre,
  combineReducers,
  applyMiddleware
} from 'redux';

const reducers = combineReducers(todosReducer, filterReducer);

const enhancers = applyMiddleware(logger, crashReporter);

const store = createStore(reducers, enhancers);

完整程式碼實作:https://codesandbox.io/s/react-todomvc-redux-middleware-tugoii

現在任何被 dispatch 到 store 的 action 都將經過 logger 和 crashReporter

Next

理解完 React Middleware 的運作原理後,我們可以繼續來看看有哪些實務上大家都在使用 Redux Middleware,以及它們分別幫忙解決了什麼問題。

Reference

https://max80713.medium.com/%E8%A9%B3%E8%A7%A3-redux-middleware-efd6a506357e

https://pjchender.dev/react/redux-middleware/

https://chentsulin.github.io/redux/docs/advanced/Middleware.html


上一篇
Day 21 全站狀態管理的利器 - Redux (三) 元件使用 Redux
下一篇
Day 23 Redux 非同步 Action 解決方案 - redux-thunk
系列文
開始搞懂React生態系30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言