Redux 编程:解决异步请求数据更新不及时问题

阅读时长 8 分钟读完

前言

现代的前端开发已经离不开前端数据访问了,尤其是涉及到实时数据处理的业务需求更是如此。在数据处理的过程中,异步请求得到的数据更新不及时是一个很常见的问题。本文将介绍如何使用 Redux 编程来解决这个问题。

Redux 简介

Redux 是一个用于 JavaScript 应用程序的可预测状态容器。它可以让你管理整个应用程序的状态,使状态更新更加方便和可控。Redux 有三个基本原则:

  1. 单一数据源:整个应用程序的状态由一个 store 保存。任何时候,应用程序只有一个数据源,它使得整个应用程序的状态变得更加可控。
  2. 状态是只读的:状态的更新是通过 dispatching actions 实现的, action 是一个描述状态变化的普通对象,它必须包括一个 type 属性。Reducers 是一些纯函数,它们根据当前的 state 和 action 返回一个新的 state。
  3. 状态更改是纯函数:为了描述 action 如何更改 state,我们需要编写 reducers。Reducer 只是接收当前状态和一个描述如何更改状态的 action,并返回新的状态。

Redux 状态管理模式使得我们可以更好地控制整个应用程序的状态,管理数据和减少对非纯函数的依赖。

解决异步请求数据更新不及时的问题

在前端开发中,异步请求是一项关键任务。例如,通过 fetch,axios,jQuery Ajax 或 WebSocket 等方法从服务器获取数据时,我们需要将请求的数据存储在 store 中,并使用组件来显示数据。但是,由于异步请求的时间不确定,我们可能会在某些情况下看到过时的状态。

Redux 的解决方案是在异步请求的生命周期中触发不同的 action,从而更新 store。这可以通过 Redux Thunk 来实现。

Redux Thunk 允许我们在 action creators 中返回一个函数,而不是一个普通的对象,这个函数可以包含异步操作。当异步操作结束时,我们可以再次 dispatch 另一个 action 来更新 store。

安装 Redux Thunk

在使用 Redux Thunk 之前,我们需要安装它。可以使用 npm 安装它:

createAsyncThunk 函数的使用

Redux Toolkit 提供了一个 createAsyncThunk 函数,用于为异步操作创建标准 action creators 和 reducers。这个函数在每个阶段都帮助您处理同步 action。

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

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

示例代码

我们从一个简单的例子开始,该例子获取用户数据。在这个例子中,我们使用 Redux Thunk 来获得实时数据。

index.js

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

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

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

在这里,我们创建了一个 store ,它有一个 userReducer 来管理用户相关的状态。

userSlice.js

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

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

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

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

在这里,我们使用 createSlice 函数来定义一个 userSlice ,这个 slice 是相应状态的 reducer,reducer 定义了三个状态:dataloadingerror

extraReducers 定义了三个异步操作的状态:pendingfulfilledrejected。在异步操作时,我们将状态变更为 loading,在获取数据完成后,我们将数据存储到 data 中,并将 loading 重新更改为 false。如果发生错误,我们将 loading 设置为 false 以及将错误信息存储到 error 中。

userApi.js

我们可以在 Github 上查找 Redux Thunk 参考文档和源代码。

通过组件从 store 中获取数据

下面是一个简单的组件,它接收一个 userId 作为输入,然后根据 userId 获取用户数据。

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

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

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

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

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

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

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

在这个组件中,我们使用 useSelector 钩子来从 state 中获取数据,useDispatch 钩子用于 dispatch action 来 fetch 数据。useEffect 钩子在组件挂载时触发,然后获取数据。

如果数据正在加载中,我们将显示一个 <div>Loading...</div>。在发生错误时,我们显示错误信息。当获取数据完成后,我们将数据渲染到组件上的相应位置。

结论

Redux Thunk 允许我们在 action creators 中返回函数,以便异步操作可以更新 store,解决了异步请求数据更新不及时的问题。使用 createAsyncThunk 可以简化很多操作,从而使我们更专注于数据处理和状态管理方面的事情。

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

纠错
反馈