使用 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中文网其他相关文章!