React+Redux 异步请求数据的处理方案

阅读时长 7 分钟读完

在现代Web开发中,异步请求数据已经成为了前端开发中不可避免的一部分。无论是从后端获取数据还是与第三方接口通信,异步请求数据都是我们必不可少的一项技术。而React和Redux是当今最常用的前端框架,本文将介绍在React和Redux中,如何处理异步请求数据的最佳实践。

Redux-thunk 中间件

Redux-thunk是Redux中最常用的中间件之一,它允许我们在action中返回函数,而不必非要返回一个action对象。当我们调用通过thunk返回的函数时,它可以封装异步请求和action的dispatch。下面就是一个简单的实例:

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

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

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

异步请求数据处理的流程

与以往不同的是,在React+Redux中,我们需要处理异步请求数据的过程要分为三个步骤:

  1. 定义action creator
  2. 定义reducer
  3. 完成剩余的UI组件

在这三个步骤中,第一个和第二个步骤是比较纯粹的Redux操作,而在第三个步骤中,我们需要做的就是将异步请求后得到的数据以及Redux中的state,进行交互。

action creator

在Redux中,action creator是获取数据的第一步。它是一个函数,会返回action对象。在Redux+React中,action creator中除了返回action对象外,还会返回一个函数类型的返回值,并传递绑定到组件上的dispatch方法作为参数,这个函数内部再完成实际的异步请求。

实现方式如下:

上述代码中,我们定义了一个fetchData方法,返回了一个函数。该函数使用了Redux-thunk中间件,可以接受dispatch函数,并使用它派发了一个FETCH_DATA的action。FETCH_DATA的payload是我们从异步请求中获得的数据。

reducer

reducer是Redux中更改state的唯一途径。我们从异步请求获得数据之后需要将它放入state中并将整个state一并返回,这个过程需要在reducer中进行。

一个tip是,当action是异步请求的时候,最好定义两个action type:一个是请求开始的type,一个是请求结束的type。这样可以让你更好的控制应用程序的状态,以及对应的UI组件的行为。

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

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

在上述代码中,state中的content、loading、error属性是为了UI组件提供表现效果。在reducer中,我们维护了state的初始状态,每次接收到action之后都需要将当前的state更新,并且根据action中的type来确定更新内容。

UI组件

UI组件是我们最终要展示的内容,因此,我们需要考虑如何将Redux中的数据与UI组件结合起来。这也是我们本文中想要讨论的最后一部分,这个问题有好几个解决方案。这里介绍两种:

React+Redux 传递state和actions

首先,我们将使用React和Redux的connect函数把state和action传递到UI组件中。当我们在UI组件中使用props中的数据时,Redux中的数据也被自动更新。

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

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

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

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

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

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

在上面的代码中,我们将redux的state和action,通过connect函数和UI组件进行了连接,而UI组件能通过props获取到所需的数据。

React-Redux和Redux-saga

另外,我们还可以借助React-Redux和Redux-saga中间件,来实现完全将异步请求处理塞到saga中的方案。这将更彻底地将异步请求与UI组件分离,并让UI组件只关注状态的改变。

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

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

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

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

在上述代码中,我们将异步请求过程封装到了saga中。saga是一个处理副作用的库,它通过将异步执行由generator语法所包裹的函数,来找到不同的效用和副作用。

通过Saga这样的方式,我们可以更好的解耦异步请求中的副作用。这样,UI组件方只需要关心状态的变化即可。

结论

本文介绍了在React+Redux中,处理异步请求数据的方案,并从action creator、reducer、UI组件三个角度来阐述整个处理流程,最后我们提供了两种方案供大家选择。

以上两种方案都值得我们深思,方案的最终选择应该根据项目的具体情况而定。我们期望本文能够帮到大家成为一名更好的React+Redux开发者,并更好地实践异步请求数据的最佳实践。

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

纠错
反馈