使用 Redux 和 Reselect 进行数据筛选和缓存

阅读时长 16 分钟读完

随着 Web 应用程序变得越来越复杂,管理数据状态变得越来越困难。Redux 是一个流行的状态管理库,可以帮助我们轻松地跟踪应用程序的状态。另一个非常有用的库是 Reselect,它可以帮助我们在应用程序中进行数据筛选和缓存。

本文将介绍 Redux 和 Reselect,并演示如何在前端开发中使用它们进行数据筛选和缓存。我们将首先探讨 Redux 的工作原理,然后深入研究 Reselect。最后,我们将演示如何使用这些库来构建一个实际的示例应用程序。

Redux 简介

Redux 是一个用于管理状态单一数据源的 JavaScript 库。它基于 Flux 架构,使用 action、reducer 和 store 的概念来更新应用程序的状态。

  • Action 是将数据从应用发送到 store 的有效载荷。它们是 store 唯一的来源。
  • Reducer 描述如何更新应用程序状态,并处理 action。
  • Store 将应用程序的所有状态存储在一个单一的对象中,并且只能通过使用 reducer 更新状态。

Redux 的状态由多个 reducer 对象组成。这些 reducer 函数接受一个先前的状态和 action,然后返回新的状态。Redux 将这些新状态合并为单个状态树。

Reselect 简介

Reselect 是一个用于创建可记忆的选择器函数的库。选择器函数将计算和返回衍生数据。Reselect 可以提高应用程序的性能,因为它会缓存选择器函数的结果并仅在其输入更改时重新计算。

  • Selector 函数将状态作为参数,并返回计算值。
  • Memoized selector 是指通过使用缓存来提高效率而创建的选择器函数。

使用 Reselect,我们可以轻松地创建和组合选择器函数。每个选择器函数都返回一个 memorized selector。这个选择器具有缓存功能,仅在其输入发生变化时重新计算。

如何使用 Redux 和 Reselect 进行数据筛选和缓存

现在我们知道了 Redux 和 Reselect 的概念,我们可以将它们结合起来来实现数据筛选和缓存。我们将开发一个示例应用程序,该应用程序允许用户浏览商品列表并按类别过滤它们。应用程序还允许用户将某些商品添加到购物车中。

步骤 1:准备工作

首先,我们需要安装依赖项并设置 Redux Store。我们将创建一个包含商品和购物车商品的对象的全局状态。该对象会存储在 Redux store 中。这将使我们能够轻松地更新和访问应用程序的状态。

这是一个示例的 store.js 文件:

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

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

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

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

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

我们的初始状态包括一个商品列表和一个空的购物车数组。

步骤 2:创建适当的 Action

接下来,我们需要创建商品和购物车相关的 action。因此,我们将分别创建两个 Action 类型和它们对应的 Action Creator。

有两个 action 类型,在 actions.js 文件中定义如下:

接下来,我们创建一个 addProductToCart 动作创建器:

最后,我们创建一个 filterProductsByCategory 动作创建器:

步骤 3:编写相应的 Reducer

为了响应前面创建的 action,我们需要编写两个 reducer。第一个 reducer 将处理添加商品到购物车的情况,第二个 reducer 将处理按类别过滤商品的情况。

让我们分别对两个 reducer 进行介绍。

首先是 cart.js 文件:

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

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

第二个是 products.js 文件:

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

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

当我们只想根据类别过滤商品时,我们将 state 中的 products 改为一个经过过滤后的数组。这里要注意,我们要保存原始数组,以便在不带筛选器的情况下显示所有商品。

步骤 4:创建及组合 Selector 函数

现在我们需要使用 Reselect 来创建并组合选择器函数。我们将首先创建一个基本选择器来获取商品和类别筛选器的状态。

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

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

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

getProducts 选择器函数中,返回 Redux store 中的 products 数组。在 getCategoryFilter 函数中,返回 Redux Store 中存储的 categoryFilter 字符串。这些选择器函数用于创建 getVisibleProducts 函数。

getVisibleProducts 函数接受两个参数:getProductsgetCategoryFilter。最后,我们调用了 createSelector 方法来指定选择器的输入和输出。它将输入选择器作为第一个参数,然后是计算函数。计算函数接收每个输入选择器的结果作为参数。

最后,我们在 filterProductsByCategory action 中,调用 getVisibleProducts compute 函数,并使用返回结果来更新应用程序的状态。

这个组件我们使用 react-redux 中的 connect 方法来将选择器注入到组件中。

现在我们已经准备好在商品列表中按类别过滤并将商品添加到购物车中。我们使用上述步骤中创建的 action、reducer 和 selector 来构建应用程序。

示例代码如下:

store.js:

actions.js:

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

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

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

reducers/cart.js:

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

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

reducers/products.js:

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

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

selectors/products.js:

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

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

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

components/Product.js:

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

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

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

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

components/ProductList.js:

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

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

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

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

components/CategoryFilter.js:

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

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

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

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

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

components/Cart.js:

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

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

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

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

App.js:

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

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

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

结论

在本文中,我们介绍了 Redux 和 Reselect,并演示了如何将它们组合在一起有效地筛选和缓存数据。我们创建了选择器函数,使我们能够轻松地在应用程序中进行筛选,并只在需要时才计算计算值。这提高了应用程序的性能,并使我们的代码更易于维护。

当您在构建大型应用程序时,使用 Redux 和 Reselect 将是一种非常有用的技术。它们可以轻松地帮助您管理和控制应用程序的状态,同时提高应用程序的性能。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6732b9070bc820c5823e81ad

纠错
反馈