Skip to main content

One post tagged with "react"

View All Tags

Redux Saga 真好用

· 3 min read

最近相當常使用Redux Saga,簡單紀錄一下。

比較常見用來處理 Redux 非同步操作的 Middleware 有redux-thunk, redux-saga, redux-observable等。之前參與開發的Firefox Devtools使用的是修改版的redux-thunk。我在其中一個個人專案中也有試過redux-observable。使用 Rxjs 的感覺,是整個過去的開發觀念又被扭成另一個形狀😅。因為整套開發的觀念不同,當後續想要修改時常常遇到一些問題。目前則多使用redux-saga來處理非同步相關問題。

基本 Redux State 運作​

先簡單回顧一下基本的 Redux State 運作。Redux 統一儲存所有網頁前端的狀態 (State)。只能透過發送Action來通知狀態的改變,並透過Reducer修改當前的狀態。

基本的 Redux 僅支援同步的操作。若想支援非同步操作(promise, async, API 等)需要透過加裝Middleware來處理。Middleware 的功用,是改變收到Action後的處理流程。Redux Saga即是其中一種功能強大的 Middleware。

Redux Saga 運作​

Redux Saga 的運作模型,起始自收到 Action。Saga 透過takeLatest或take監聽想處理的 Action,並呼叫對應的 generator function。在 generator function 中,可以用yield語句來完成各種非同步操作。

例如使用select語句來從目前的State中取得資料,使用call語句來呼叫 API,用put語句來將新的 Action 傳回 Redux 處理。

一段簡單的範例:

function* handleAction(action) {
// get state from state.auth
const auth = yield select((state) => state.auth)
// async get data. fetchData is the async function.
const { result } = yield call((auth) => fetchData(auth))
// dispatch action. saveData is the action creator.
yield put(actions.saveData(result))
}

export default function* rootSaga() {
yield takeLatest('ACTION', handleAction)
}

把兩張圖畫在一起的話,可以看到 Redux state 與 Redux Saga 之間整體的呼叫關係。使用 Redux/Redux Saga 能將「從 UI 呼叫 -> 參看現有狀態來與 API 溝通 -> 根據取回值更新狀態 -> 更新 UI」這樣的複雜流程,整個簡化為單向的操作。

當然Redux-saga還有提供一些其他的功能,但其實Redux-saga就是這麼簡單。使用Redux-saga可以很好地運用原有的非同步處理觀念,要將 React Component 中相應的非同步函式搬出來,也不像Redux-observable那樣需要全部改寫。

參考資料​