简介
redux-saga-crud-service 是一个针对 Redux-Saga 应用中常用的 CRUD 操作的辅助工具类。该 npm 包提供了一系列高度封装的 API,可以有效地节省开发者编写 CRUD 相关action 和 saga 的时间,以及降低了开发过程出现错误的概率。
安装
使用该 npm 包前,您需要确保安装了以下依赖:
- Redux: ^4.0.0
- Redux-saga: ^1.0.0
- Axios: ^0.18.0
您可以通过 NPM 或 Yarn 安装,我们以 NPM 为例:
npm install redux-saga-crud-service --save
使用方法
当您安装完该 NPM 包后,您可以在 reducer 和 saga 中使用它提供的工具类。
创建 reducer
在 redux 中配置 reducer 时,您可以使用 redux-saga-crud-service 提供的方法来快速生成基于 CRUD 操作的 reducer,您可以参考以下代码:
-- -------------------- ---- ------- ------ - ------------- - ---- -------------------------- ----- ----------- - --------------- -------- ------- -- -- --------- ---------- ----- ------ ----- --- -------- ------- ------- -- - ----- - ---- - - --------------- ------ - --------- ----- ---------- ------ ------ ----- - -- -------- ------- ------- -- -- --------- ---------- ------ ------ --------------------- --- ------ ----- -- ------------- -- -------------- ------ ------- ------------
创建 saga
在配置 saga 时,您可以使用以下内容:
- buildSaga 函数生成与服务端交互的 saga worker。该函数需要传入请求类型(
REQUEST_TYPE
)和卸载类型(CLEAR_TYPE
):
-- -------------------- ---- ------- ------ - --------- - ---- -------------------------- ----- -------------- - ----------- ------------- ---------------- ----------- -------------- ------- ------ --------- ------------------ --- --------- ------------- - ----- --------------------------- ---------------- -
- watchListService 函数生成监听工具,该工具可以监听某个 reducer,当 redux state 发生变化时,则会自动调用相应的 Request Action。
import { watchListService } from 'redux-saga-crud-service'; function* exampleWatchService() { yield fork(watchListService, { REQUEST: EXAMPLE_REQUEST }); }
示例代码
我们编写了一个简单的例子以展示如何使用 redux-saga-crud-service 来实现 CRUD 操作。我们假设在我们的应用中,我们需要基于用户的资料表,以获取、更新和删除存在于数据中的资料。
初始状态
我们的 Redux store 初始状态需要指定以下属性:
-- -------------------- ---- ------- -- ---------- ------ - ---------------- ---------------- ----------- - ---- -------- ------ -------------------- ---- ------------- ------ ----------- ---- ------------------------- ------ ----------- ---- ------------------------- ------ - --------------- --------------- - ---- ----------------- ----- ----------- - ----------------- ------------ ------------ --- ----- -------------- - ----------------------- ----- ----- - ------------ ------------ -------------------------------- -- ----------------------------------- ----------------------------------- ------ ------- ------
-- -------------------- ---- ------- -- ------------------------- ------ - ------------- - ---- -------------------------- ----- ------------ - - ----- --- ---------- ------ ------ ----- -- ----- ----------- - --------------- -------- ------- -- -- --------- ---------- ----- ------ ----- --- -------- ------- ------- -- - ----- - ---- - - --------------- ------ - --------- ----- ---------- ------ ------ ----- - -- -------- ------- ------- -- -- --------- ---------- ------ ------ --------------------- --- ------ ----- -- ------------- -- -------------- ------ ------- ------------
-- -------------------- ---- ------- -- ------------------------- ------ - ------------- - ---- -------------------------- ----- ------------ - - ----- --- ---------- ------ ------ ----- -- ----- ----------- - --------------- -------- ------- -- -- --------- ---------- ----- ------ ----- --- -------- ------- ------- -- - ----- - ---- - - --------------- ------ - --------- ----- ---------- ------ ------ ----- - -- -------- ------- ------- -- -- --------- ---------- ------ ------ --------------------- --- ------ ----- -- ------------- -- -------------- ------ ------- ------------
-- -------------------- ---- ------- -- ----------------- ------ - ---- ----- ---------- - ---- --------------------- ------ - ---------------- -------------- ----------------------- --------------------- ----------------------- --------------------- ----------------------- --------------------- - ---- ------------------------- ------ - --------- - ---- -------------------------- ------ - ---------------- - ---- -------------------------- ----- -------------- - ----------- ------------- ---------------- ----------- -------------- ------- ------ --------- ------------------ --- ----- -------------------- - ----------- ------------- ----------------------- ----------- --------------------- ------- ------ --------- ----------------------- --- ----- -------------------- - ----------- ------------- ----------------------- ----------- --------------------- ------- ------ --------- ----------------------- --- ----- -------------------- - ----------- ------------- ----------------------- ----------- --------------------- ------- --------- --------- ----------------------- --- --------- -------------------- - ----- --------------------------- ---------------- - --------- -------------------------- - ----- ---------------------------------- ---------------------- - --------- -------------------------- - ----- ---------------------------------- ---------------------- - --------- -------------------------- - ----- ---------------------------------- ---------------------- - ------ --------- ---------------- - ----- ----- ------------------------- ------------------------------- ------------------------------- ------------------------------- --- - ------ --------- ---------------- - ----- ---------------------- - -------- ---------------------- --- -
监听请求
我们首先需要实现从后端提取信息的 exampleService
,它与 CRUD 操作中的“获取”操作对应,我们需要发送 HTTP GET 请求以获取整个表格的内容。我们在 example-saga.js
中定义该 service 的 implementation:
-- -------------------- ---- ------- ------ - ---------------- -------------- - ---- ------------------------- ------ - --------- - ---- -------------------------- ----- -------------- - ----------- ------------- ---------------- ----------- -------------- ------- ------ --------- ------------------ ---
在将 service 与 Saga 绑定之前,我们需要先生成一个 reducer,该 reducer 可以接收到 Redux state 中的请求信息。我们在 example-list-reducer.js
中定义该 reducer 的 implementation:
-- -------------------- ---- ------- ------ - ------------- - ---- -------------------------- ----- ------------ - - ----- --- ---------- ------ ------ ----- -- ----- ----------- - --------------- -------- ------- -- -- --------- ---------- ----- ------ ----- --- -------- ------- ------- -- - ----- - ---- - - --------------- ------ - --------- ----- ---------- ------ ------ ----- - -- -------- ------- ------- -- -- --------- ---------- ------ ------ --------------------- --- ------ ----- -- ------------- -- -------------- ------ ------- ------------
我们需要在 Saga listener 中让 exampleService 与 exampleList reducer 绑定。我们在 example-saga.js
中实现该任务:
-- -------------------- ---- ------- ------ - ---- ----- ---------- - ---- --------------------- ------ - ---------------- -------------- - ---- ------------------------- ------ - --------- - ---- -------------------------- ------ - ---------------- - ---- -------------------------- ------ ----------- ---- ------------------------- -- --- --------- -------------------- - ----- --------------------------- ---------------- - --------- --------------------- - ----- ---------------------- - -------- --------------- --- - ------ --------- ---------------- - ----- ----- ------------------------- -------------------------- -- --- --- -
显示数据列表
当监听器与服务绑定后,我们现在可以使用 Redux store 中的数据了。我们需要将变量例 exampleList
转化为 React 组件的 props 并传递给视图层。该组件将会用于在页面中显示列表的信息。
-- -------------------- ---- ------- -- ----------------- ------ ------ - --------- - ---- -------- ------ - ------- - ---- -------------- ------ ----------- ---- ------------------------- ----- ----------- ------- --------- - -------- - ----- - ---- - - ----------- ------ - ----- ------------------- ------ -- - -- ------------------------------ --- ------ -- - - ----- --------------- - ----- -- -- ----- ----------------------- --- ------ ------- --------------------------------------
获取单个信息
接下来,我们需要定义与“获取单个信息”对应的 Redux state、reducer、saga-worker 和 API 路由。该任务与 exampleList
相似,区别在于我们需要将 reducer 初始值设置为空对象,该任务在 exampleItemReducer 文件中以如下实现:
-- -------------------- ---- ------- -- ------------------------- ------ - ------------- - ---- -------------------------- ----- ------------ - - ----- --- ---------- ------ ------ ----- -- ----- ----------- - --------------- -------- ------- -- -- --------- ---------- ----- ------ ----- --- -------- ------- ------- -- - ----- - ---- - - --------------- ------ - --------- ----- ---------- ------ ------ ----- - -- -------- ------- ------- -- -- --------- ---------- ------ ------ --------------------- --- ------ ----- -- ------------- -- -------------- ------ ------- ------------
该 reducer 会接收 EXAMPLE_DETAIL_REQUEST
请求,然后检索 redux store 中的值来查找特定 ID 的数据,并将其作为 props 传入视图层组件以显示信息:
-- -------------------- ---- ------- ------ ------ - --------- - ---- -------- ------ - ------- - ---- -------------- ------ ----------- ---- ------------------------- ----- ----------------- ------- --------- - -------- - ----- - ---- - - ----------- ------ - ----- ------------------ ------------------------- ------ -- - - ----- --------------- - ----- -- -- ----- ----------------------- --- ------ ------- --------------------------------------------
基于 ID 更新一行
当使用者提交一个表格更新的操作,我们需要向后端传递 ID 和新数据。我们需要生成与 PUT API 路由相对应的 saga worker。关键操作如下所示。
-- -------------------- ---- ------- ------ - ----------------------- --------------------- - ---- ------------------------- ------ - --------- - ---- -------------------------- ----- -------------------- - ----------- ------------- ----------------------- ----------- --------------------- ------- ------ --------- ----------------------- ---
同时,我们需要实现一个表单来允许使用者编辑一行的信息。在提交更新请求后,我们可以使用 Promise 来使页面重定向到详细页面或列表。具体实现如下所示:
-- -------------------- ---- ------- ------ ------ - --------- - ---- -------- ------ - ------- - ---- -------------- ------ ----------- ---- ------------------------- ------ - ---------------------- - ---- ------------------------- ----- ----------------- ------- --------- - ------------------ - ------------- ---------- - - ----- --- ------------ --- -- - ------------------- - ----- - --------- ----- - - ----------- ---------- ----- ----------------------- -------- - --- --------------- - --- - ------ - --- -- - ------------------- ----- - --------- ------ ------- - - ----------- ----- - ----- ----------- - - ----------- ------ --- --------------- -- - ---------- ----- ----------------------- -------- - --- ---------------- ----- - ----- ------------ -- -------- -- --- ---------- -- --------------------------------------------- - ---------------- - --- -- - --------------- ----- -------------- --- - ----------------------- - --- -- - --------------- ------------ -------------- --- - -------- - ----- - ---- - - ----------- ----- - ----- ----------- - - ----------- ------ - ----- ----------------------- ------ ----------- ------------ -------------------------------- -- ------ ----------- ------------------- --------------------------------------- -- ------- ----------------------------- ------- -- - - ----- --------------- - ----- -- -- ----- ----------------------- --- ------ ------- --------------------------------------------
删除特定 ID 的行
最后,我们需要在视图层中提供一个按钮,可以触发发送一个 DELETE 请求,用于删除某一行。当 API 返回“成功”后,页面应该重新定向到列表页。
-- -------------------- ---- ------- ------ ------ - --------- - ---- -------- ------ - ------- - ---- -------------- ------ ----------- ---- ------------------------- ------ - ---------------------- - ---- ------------------------- ----- ----------------- ------- --------- - ---------- - -- -- - ----- - --------- ------ ------- - - ----------- ---------- ----- ----------------------- -------- - --- ---------------- -------- -- -- ------------------------- -- --- - -------- - ----- - ---- - - ----------- ------ - ----- ------------------ ------------------------- ------- ----------------------------------------- ------ -- - - ----- --------------- - ----- -- -- ----- ----------------------- --- ------ ------- --------------------------------------------
结论
在本文中,我们介绍了如何使用 redux-saga-crud-service 模块来快速生成 Redux-Saga 应用程序的 CRUD 全套操作。我们编写了一个示例应用,该应用演示了如何实现“获取表格数据”、“获取一个数据”、“更新一个数据”和“删除一个数据”这四种操作,以及如何生成相应的 Redux state、reducer、saga-worker 和 router。
我们希望这篇文章能够为初学者提供一定的指导,借助 redux-saga-crud-service 的力量可以轻松完成 CRUD 相关操作。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6005682f81e8991b448e448c