使用 Redux Saga 簡化 React/React Native 專案中的 API 工作流程
本文並非專家級指南,但將盡力解釋如何利用 Redux Saga 在你的 React 或 React Native 專案中處理副作用。如果你的應用程式涉及大量 API 調用,Redux Saga 能簡化流程,讓程式碼更容易管理。
為什麼選擇 Redux Saga?
Redux Saga 是一款中間件,能以清晰可預測的方式管理副作用(如 API 呼叫)。無需在元件或 reducer 中塞滿 API 邏輯,你可以將這些任務委託給 saga。 Saga 允許你寫一個看起來同步的非同步程式碼,使用名為生成器的特殊 JavaScript 函數。
設定資料夾結構
在深入研究 saga 之前,請務必為專案組織好結構,以便擴展。以下是我遵循的基本結構:
Services 資料夾包含可重複使用的 API 呼叫函數。以下是一個「更改密碼」API 的範例:
<code class="language-javascript">// ChangePasswordService.js import {Constants} from '../../Config'; import Ajax from './base'; const BASE_URL = Constants.IS_DEVELOPING_MODE ? Constants.BASE_URL.DEV : Constants.BASE_URL.PROD; export default { ChangePassword: async params => { return fetch(`${BASE_URL}api/change-password`, { method: 'POST', body: params, headers: { Accept: 'multipart/form-data', }, }) .then(response => Ajax.handleResponse(response)) .then(data => { console.log('Data', data); return data; }); }, };</code>
此處,我們定義了一個 ChangePassword 函數來進行 API 呼叫。它使用 fetch 發送 POST 請求到端點,並使用輔助函數 (Ajax.handleResponse) 處理回應。
Reducers 監聽分發的 action 並相應地更新狀態。下面是一個用來管理密碼變更的 reducer:
<code class="language-javascript">// PasswordChangeSlice.js import {createSlice} from '@reduxjs/toolkit'; const passwordChangeSlice = createSlice({ name: 'passwordChange', initialState: { data: null, isChangeSuccess: null, error: null, message: null, }, reducers: { changePassword: state => { state.isChangeSuccess = null; state.error = null; state.message = ''; }, changePasswordSuccess: (state, action) => { state.data = action.payload; state.message = 'Password changed successfully'; state.isChangeSuccess = true; }, changePasswordFail: (state, action) => { state.error = action.payload; state.message = 'Something went wrong'; state.isChangeSuccess = false; }, }, }); export const {changePassword, changePasswordSuccess, changePasswordFail} = passwordChangeSlice.actions; export default passwordChangeSlice.reducer;</code>
此 reducer 有三個 action:
changePassword
:請求開始時重置狀態。 changePasswordSuccess
:使用成功資料更新狀態。 changePasswordFail
:使用錯誤訊息更新狀態。 現在進入重點! Saga 處理實際的 API 調用,並根據回應分發 action。這是一個「更改密碼」API 的 saga:
<code class="language-javascript">import {all, call, put, takeEvery} from 'redux-saga/effects'; import API from '../Services/ChangePasswordService'; import { changePasswordFail, changePasswordSuccess, } from '../Reducers/PasswordChangeSlice'; function* changePasswordSaga({payload}) { try { const response = yield call(API.ChangePassword, payload); if (response?.data) { yield put(changePasswordSuccess(response.data)); } else if (response?.errors) { yield put(changePasswordFail(response.errors)); } } catch (error) { yield put(changePasswordFail(error.message)); } } function* passwordSaga() { yield all([ takeEvery('passwordChange/changePassword', changePasswordSaga), ]); } export default passwordSaga;</code>
call
:呼叫 API 函數 (API.ChangePassword) 並等待結果。 put
:分發 action 來更新狀態。 takeEvery
:監聽特定 action (changePassword
) 並觸發對應的 worker saga (changePasswordSaga
)。 如果 API 呼叫成功,saga 將分發 changePasswordSuccess
;如果失敗,則分發 changePasswordFail
。
為了觸發流程,我們建立一個自訂 hook 來分發 changePassword
action:
<code class="language-javascript">// useChangePasswordActions.js import {useDispatch, useSelector} from 'react-redux'; import {changePassword} from '../Reducers/PasswordChangeSlice'; export const useChangePasswordActions = () => { const dispatch = useDispatch(); const passwordState = useSelector(state => state?.changePassword); const changePasswordCall = params => { dispatch(changePassword(params)); }; return { passwordState, changePasswordCall, }; };</code>
工作原理
changePasswordCall
。 changePassword
action 更新狀態以指示正在進行請求。 changePassword
並觸發 worker saga。 總結
這個設定將你的 API 工作流程組織成清晰且易於管理的步驟:
記住,這只是組織專案的一種方式。如果你有更多經驗或想法,請隨時評論你的策略。我將在以後的文章中隨著學習和改進而涵蓋更多關於 saga 的內容。
祝程式設計愉快! ?
以上是如何為 API 呼叫製作 Redux Saga 流程?的詳細內容。更多資訊請關注PHP中文網其他相關文章!