npm 包 redux-functional-reducer 使用教程

React 和 Redux 一直是前端开发中最流行和最强大的框架之一。React 用于构建 User Interface,而 Redux 则用于管理应用程序的状态。Redux 提供了一个简单且可预测的数据流方案,使得在复杂应用中管理状态变得方便。然而,Redux 的 reducer 处理方式需要程序员熟练使用语言特性和设计模式。为了解决这个问题,出现了 redux-functional-reducer 这个包。

redux-functional-reducer 是什么?

简单来说,redux-functional-reducer 是一个可视化工具,它可以帮助我们更好地管理应用程序的状态。它使用函数式编程风格处理状态管理,不再是传统的 switch 和 if/else 控制流编写,更符合现代 JS 语言特性和风格。

redux-functional-reducer 提供了四个高阶 reducer,分别是 composeReducers, mapReducers, whenRejectedwhenUnhandled,我们会在下面的示例中详细了解它们。

安装

安装 redux-functional-reducer 很简单,使用 npm 安装:

--- ------- ------------------------

使用

为了更好地说明如何使用 redux-functional-reducer,我们将创建一个具有如下功能的简单应用:

  • 一个 todo 列表
  • 可以添加、删除和完成 todo

我们将从 Redux 基础模板开始,并使用 redux-functional-reducer 优化我们的 reducer。

基础模板

我们从最基础的 Redux 模板开始,它包含了一个简单的 todo 的 actions 和 reducer:

----- -------- - -----------
----- ----------- - --------------

----- ------------ - -
  ------ --
--

-------- ------------------ - ------------------- ------- -
  ------ ------------- -
    ---- ---------
      ------ -
        ---------
        -
          --- ------------ - --
          ----- ------------
          ---------- -----
        -
      --
    ---- ------------
      ------ -------------- --
        ------- --- --------- - - -------- ---------- --------------- - - ----
      --
    --------
      ------ ------
  -
-

------ ------- -------------

这个模板很简单,只有两个 actions 和一个 reducer,但是在复杂的应用程序中,reducer 通常是一大块 switch 和 if/else 语句。因此,我们使用 redux-functional-reducer 来优化这个 reducer。

使用 redux-functional-reducer

接下来,我们将使用 redux-functional-reducer 来编写我们的 reducer。

首先,由于我们的应用程序中有多个 reducers,我们需要使用 combineReducers 将它们组合起来,生成一个根 reducer。然后,我们使用 composeReducerstodosReducer 编写成函数式 reducer。

------ - --------------- - ---- --------
------ - --------------- - ---- ---------------------------

----- -------- - -----------
----- ----------- - --------------

----- ------------ - -
  ------ --
--

-------- ------------------ - ------------------- ------- -
  ------ ------------- -
    ---- ---------
      ------ -
        ---------
        -
          --- ------------ - --
          ----- ------------
          ---------- -----
        -
      --
    ---- ------------
      ------ -------------- --
        ------- --- --------- - - -------- ---------- --------------- - - ----
      --
    --------
      ------ ------
  -
-

----- ----------- - -----------------
  ------ ----------------
    -------------
    -------------------- -- ----------------------- ------- -----------------
  -
---

我们组合了 todosReducer 和 whenUnhandled。whenUnhandled 用于捕捉 todo actions 以外的 actions,防止我们的 reducer 抛出错误。

mapReducers 控制多个 reducer

现在我们想增加一个新的 reducer,用于控制 todo 的 visibilityFilter(过滤器)。

----- --------------------- - ------------------------

----- ----------------------- - ------ - ----------- ------- -- -
  -- ------------ --- ---------------------- -
    ------ --------------
  -
  ------ ------
--

在 rootReducer 中,我们需要为两个 reducer 分别提供 action。

----- ----------- - -----------------
  ----------------- ------------------------
  ------ ----------------
    -------------
    -------------------- -- ----------------------- ------- -----------------
  -
---

很显然,我们需要手动的将 action 传递给每个 reducer。此时,我们需要 mapReducers

------ - --------------- - ---- --------
------ - ---------------- ------------ ------------- - ---- ---------------------------

----- -------- - -----------
----- ----------- - --------------
----- --------------------- - ------------------------

----- ------------ - -
  ----------------- -----------
  ------ --
--

-------- ------------------ - ------------------- ------- -
  ------ ------------- -
    ---- ---------
      ------ -
        ---------
        -
          --- ------------ - --
          ----- ------------
          ---------- -----
        -
      --
    ---- ------------
      ------ -------------- --
        ------- --- --------- - - -------- ---------- --------------- - - ----
      --
    --------
      ------ ------
  -
-

----- ----------------------- - ------ - ------------------------------ ------- -- -
  -- ------------ --- ---------------------- -
    ------ --------------
  -
  ------ ------
--

----- ----------- - ----------------
  -------------
    ----------------- ------------------------
    ------ ------------
  ---
  -------------------- -- ----------------------- ------ ----- -----------------
--

------ ------- ------------

现在,我们使用了 mapReducerscomposeReducers,可以将 reducers 组合在一起,并处理所有的 action。此时,我们的应用程序状态如下:

-
  ----------------- ----------
  ------ --
-

同时,我们还通过 whenUnhandled 避免了未知 action 的错误。

whenRejected 控制异步错误

在复杂的应用程序中,API 调用和异步操作是必需的。因此,我们需要处理异步错误和在 UI 中通知错误。

当我们使用 redux-thunk 或 redux-saga 等 middleware 时,抛出 error 对 reducer 不安全,redux 异步错误处理通常使用 actions 和 reducers 的结合。因此,redux-functional-reducer 提供了 whenRejected,它是一个拦截器,负责处理 action 的 error 信息。

我们使用 React 的服务端渲染(SSR)流程来展示 whenRejected。通常,我们需要在 UI 中通知用户错误信息。

下面是一个模拟异步 API 接口,模拟返回一篇不存在的文章:

----- ---------------- - -- -- --- ----------------- ------- -- -
  ------------- -- -
    ------ -------- --- -------- -------- --- ------ ---
  -- -----
---

我们的 onError 函数可以根据返回的 error,展示错误 UI。

------ ----- ---- --------
------ - -------- - ---- --------------
------ - ---------------- ----------- - ---- --------
------ ----- ---- --------------
------ ----------- ---- -------------
------ - ---------------- ------------ -------------- ------------ - ---- ---------------------------

----- -------- - -----------
----- ----------- - --------------
----- --------------------- - ------------------------

----- ------------ - -
  ----------------- -----------
  ------ --
--

-------- ------------------ - ------------------- ------- -
  ------ ------------- -
    ---- ---------
      ------ -
        ---------
        -
          --- ------------ - --
          ----- ------------
          ---------- -----
        -
      --
    ---- ------------
      ------ -------------- --
        ------- --- --------- - - -------- ---------- --------------- - - ----
      --
    --------
      ------ ------
  -
-

----- ----------------------- - ------ - ------------------------------ ------- -- -
  -- ------------ --- ---------------------- -
    ------ --------------
  -
  ------ ------
--

----- ----------- - ----------------
  -------------
    ----------------- ------------------------
    ------ ------------
  ---
  ------------------ --------- --------- -- -
    ------------------ ------- --------- -----
    ----- ----- - ---- ------- ------- --------------- ----- ------------------
    ------ -
      ----- ------------
      -------- -----
    --
  ---
  -------------------- -- ----------------------- ------ ----- -----------------
--

------ ------- ------------

我们将 whenRejectedmapReducerscomposeReducers 中的其他 reducers 结合使用,以便能够处理 actions 和捕捉未处理的 actions。

您可能已经注意到,此时我们返回一个 action { type: 'API_ERROR', payload: '...' },稍后可以在我们的组件中处理它。

-------- ----- --------- -------- -- -
  ----- ------- --------- - -------------------
  ----- ------------ - --- -- -
    -------------------
    -------------------------
    -------------
  --

  ----- ------------------ - -- -- -
    ------ -------------------------
  --

  ------ -
    ---- ----------------
      --------------
      ----- ------------------------
        -------
          --- -----
          ------ ------------- ------------ ----------- -- ------------------------- --
        --------
        ------- -----------------------------
      -------
      ------- ---------------------------------- ----------------
      --------- -- --- -------- ------ ----- -------------------
    ------
  --
-

如果我们在组件中调用不存文章的 id,则出现这个编码错误。

------ - ---------------- - ---- --------
------ - ------------ - ---- ------------------------

----- ------------ - ---------------

------ ----- ----------- - ---- -- ----- ---------- --------- -- -
  --- -
    ----- -------- - ----- -----------------------------------
    ---------- ----- ------------- -------- -------- ---
  - ----- ------- -
    ----- - -------- ---------- - - ------
    ------------------------ ---------------- - -------- ---------- ---
    ----- ------
  -
--

发生错误后,我们在 UI 中看到了错误信息:

总结

在本文中,我们介绍了 redux-functional-reducer,并展示了如何使用它来帮助我们更好地管理 Redux 应用程序的状态。redux-functional-reducer 的 composeReducers, mapReducers, whenRejectedwhenUnhandled 提供了很多好处,帮助我们更好地组织和控制应用程序。通过使用 redux-functional-reducer,我们可以构建更健壮、更可扩展和更可维护的应用程序。

下面是完整的代码示例:

-- -----------
------ - --------------- - ---- --------
------ - ---------------- ------------ -------------- ------------ - ---- ---------------------------
------ - ---------------- - ---- --------
------ - ------------ - ---- ------------------------

----- -------- - -----------
----- ----------- - --------------
----- --------------------- - ------------------------
----- ------------ - ---------------

----- ------------ - -
  ----------------- -----------
  ------ ---
  --------- ----
--

-------- ------------------ - ------------------- ------- -
  ------ ------------- -
    ---- ---------
      ------ -
        ---------
        -
          --- ------------ - --
          ----- ------------
          ---------- -----
        -
      --
    ---- ------------
      ------ -------------- --
        ------- --- --------- - - -------- ---------- --------------- - - ----
      --
    --------
      ------ ------
  -
-

----- ----------------------- - ------ - ------------------------------ ------- -- -
  -- ------------ --- ---------------------- -
    ------ --------------
  -
  ------ ------
--

----- --------------- - ------ - ---------------------- ------- -- -
  -- ------------ --- ------------ -
    ------ ---------------
  -
  ------ ------
--

----- ----------- - ----------------
  -------------
    ----------------- ------------------------
    ------ -------------
    --------- ---------------
  ---
  ------------------ -- -
    ------------------ ------- --------- -----
    ----- ----- - ---- ------- ------- ----------------
    ------ -
      ----- ------------
      -------- -----
    --
  ---
  -------------------- -- ----------------------- ------- -----------------
--

------ ------- ------------

-- ------
------ ----- ---------------- - -- -- --- ----------------- ------- -- -
  ------------- -- -
    ------ -------- --- -------- -------- --- ------ ---
  -- -----
---

-- ----------
------ ----- ------- - ------ -- -
  ------ -
    ----- ---------
    ----
  --
--

------ ----- ---------- - ---- -- -
  ------ -
    ----- ------------
    --
  --
--

------ ----- ------------------- - -------- -- -
  ------ -
    ----- ----------------------
    ------
  --
--

------ ----- ----------- - ---- -- ----- ---------- --------- -- -
  --- -
    ----- -------- - ----- -----------------------------------
    ---------- ----- ------------- -------- -------- ---
  - ----- ------- -
    ----- - ------- - - ------
    ------------------------ ---------------- - ------- ---
    ----- ------
  -
--

-- ------
------ ----- ---- --------
------ - -------- - ---- --------------
------ - ---------------- ----------- - ---- --------
------ ----- ---- --------------
------ ----------- ---- -------------
------ - ---------------- ------------ -------------- ------------ - ---- ---------------------------
------ - -------- ----------- -------------------- ----------- - ---- ------------
------ - ------------------ ------------ - ---- ------------------------

-------- ----- -------- -- -
  ----- - ----------------- - - --------------------
  ----- ------- --------- - -------------------

  ----- ------------ - --- -- -
    -------------------
    -------------------------
    -------------
  --

  ----- ------------------ - -- -- -
    ------ -------------------------
  --

  ------ -
    ---- ----------------
      --------------
      ----- ------------------------
        -------
          --- -----
          ------ ------------- ------------ ----------- -- ------------------------- --
        --------
        ------- -----------------------------
      -------
      ------- ---------------------------------- ----------------
      ------------------ -- --------------------
      --------- -- --- -------- ------ ----- -------------------
    ------
  --
-

----- ---------- - --------

----- ----- - ------------
  ------------
  ------------------------------
--

-------- ------ -
  ------ -
    --------- --------------
      ---- ------------------------- --
    -----------
  --
-

------ ------- -----

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/60055ea381e8991b448dbfe8


猜你喜欢

  • npm 包 feathers-hooks-common2 使用教程

    简介 Npm 包 feathers-hooks-common2 是一个钩子管理库,主要用于处理在 Feathers 应用中的数据。它提供了一组常用的钩子,如 fastJoin 等,用于处理关系映射,以...

    2 年前
  • npm 包 postcss-import-webpack-resolver 使用教程

    在前端开发中,我们经常使用到 CSS 预处理器来帮助我们更加高效地书写 CSS。而 postcss-import-webpack-resolver 是一个非常强大的 npm 包,在 CSS 预处理中使...

    2 年前
  • npm 包 react-native-custom-modals 使用教程

    React Native 是一个流行的移动应用程序框架,它允许开发人员使用 JavaScript 和 React 编写原生 iOS 和 Android 应用程序。但是,使用 React Native ...

    2 年前
  • npm 包 skitter-slider 使用教程

    简介 skitter-slider 是一个基于 jQuery 的响应式图片滑块插件,可以用于网站首页的轮播图等多种图片展示需求。它提供了许多可自定义的选项,用户可以根据自己的需求来配置图片滑块。

    2 年前
  • npm 包 @scriptabuild/readonlyproxy 使用教程

    @scriptabuild/readonlyproxy 是一个用于创建只读代理的 npm 包。它可以帮助开发者更好地控制对象的访问权限,防止在不应该修改对象的情况下被修改。

    2 年前
  • npm 包 starwar-names-mis101bird 使用教程

    npm 是 Node.js 的包管理器,提供了各种各样的包以供前端开发者使用。其中 starwar-names-mis101bird 包就是一个非常实用的包,它可以让我们随机获得星球大战系列的人物名字...

    2 年前
  • npm 包 feathers-redux-immutable 使用教程

    在现代前端开发中,使用一些优秀的 npm 包可以帮助我们解决很多问题,提高开发效率和代码质量。今天,我们要介绍的是一个非常好用的 npm 包:feathers-redux-immutable。

    2 年前
  • npm 包 @makeomatic/last-release-npm 使用教程

    介绍 在前端开发中,我们经常需要关注我们使用的 npm 包的版本是否最新,尤其是当我们使用一些核心库时,这一点就更加重要。针对这个问题,@makeomatic/last-release-npm 这个 ...

    2 年前
  • npm 包 huu 使用教程

    什么是 huu? huu 是一个非常简单、轻量、易用的 JavaScript 库,它可以在你的应用程序中被用来显示引导框。它的原理是通过 DOM 操作,在页面上插入一些 HTML 元素,使用 CSS ...

    2 年前
  • npm 包 @mattlewis92/webpack-karma-die-hard 使用教程

    在前端开发领域中,Webpack 被广泛地应用于项目的打包和构建中,它的高度可配置性和强大的插件系统为我们带来了极大的便捷。而 Karma 则是一个具有实时测试、跨浏览器兼容性测试等功能的测试运行工具...

    2 年前
  • npm 包 interbit-consensus-bft 使用教程

    前言 在区块链开发中,共识算法是一个至关重要的概念。一个好的共识算法能够保证区块链网络的安全性和有效性。interbit-consensus-bft 是一个用于实现拜占庭容错(BFT)共识算法的 np...

    2 年前
  • npm 包 interbit-core-beta 使用教程

    近年来,区块链技术热度不断攀升,区块链应用也在不断地涌现。interbit-core-beta 就是一款基于区块链技术的 npm 包,通过使用该 npm 包,可以快速构建开源且安全的区块链应用。

    2 年前
  • npm 包 interbit-crypto 使用教程

    前言 在前端开发中,有时候需要对数据进行加密和解密等操作,而 interbit-crypto 这个 npm 包可以帮助我们实现这些功能。本篇文章将详细介绍 interbit-crypto 的使用方法,...

    2 年前
  • npm 包 interbit-enterprise 使用教程

    在前端开发中,npm 包是不可或缺的一部分。而 interbit-enterprise 这个 npm 包则为我们提供了一种全新的区块链部署和管理方案。本文将为大家介绍如何使用 interbit-ent...

    2 年前
  • npm 包 projectional 使用教程

    前言 projectional 是一个基于 JavaScript 的 npm 包,它提供了一种新的方式来定义和使用语言。 projectional 允许用户以图形化的方式定义其程序,而不是通过传统的文...

    2 年前
  • npm 包 interbit-micro 使用教程

    在前端开发中,我们经常需要使用各种库和框架来提高开发效率和质量。npm 是一个非常流行的 JavaScript 包管理器,其中包含了大量开源的 JavaScript 库和框架,可以满足我们日常开发中的...

    2 年前
  • `npm` 包 `webpack-parallel-uglify-es-plugin` 使用教程

    Webpack 是一个非常流行的前端打包工具,用来将多个源文件打包到一个或多个输出文件中。Webpack 强大的模块化系统和可插拔的插件系统,让其成为了前端开发者的首选打包工具。

    2 年前
  • npm 包 es-abstract-to-integer 使用教程

    JavaScript 中的数字类型被设计为可以表示整数和浮点数。在进行位运算时,如果操作数非整数,则会被自动转型为整数。由于浮点数的精度问题,可能导致转型后的整数数值不符合预期,因此需要使用转换库来保...

    2 年前
  • npm 包 interbit-core-alpha 使用教程

    简介 interbit-core-alpha 是一款基于 Interbit 2.0 的应用程序开发框架,可以方便地开发基于区块链技术的应用程序。它提供了一套丰富而易用的工具,帮助开发人员快速构建去中心...

    2 年前
  • npm 包 @bcoe/test-dependents-50 使用教程

    npm 是 Node.js 的包管理器,可以方便的管理前端项目中所需要的依赖包。而 @bcoe/test-dependents-50 是一个可以帮助我们测试依赖包的 npm 包。

    2 年前

相关推荐

    暂无文章