React 组件如何实现自身的全局状态管理

阅读时长 8 分钟读完

React 是一个非常流行的 JavaScript 前端框架,它的组件化思想让我们可以将应用程序拆分成多个独立的部分,每个部分都有自己的状态(state)。在应用程序的不同部分之间共享状态是非常常见的需求,有时候我们需要将状态从一个组件传递到另一个组件,这非常麻烦,容易出错。为解决这个问题,我们可以使用全局状态管理的技术。

在本文中,我们将讨论如何在 React 组件中实现自身的全局状态管理。我们将使用 Redux 库作为状态管理工具,因为 Redux 突出了 集中管理、极简化设计 和 状态容器理念 的两大优势。同时它还有非常成熟的生态圈并且由社区维护。

Redux 状态管理

Redux 是一个 JavaScript 库,它是一个状态容器,提供可预测的状态管理。Redux 可以让我们易于编写一些可维护且缺乏难以理解的状态更新逻辑的应用程序。Redux 将该逻辑(逻辑处理程序)打包到一个称为 reducer 的纯函数中,该函数接受现有的状态和一个操作,返回新的状态。该库还提供了一些附加的 API,使我们可以更好地控制状态和状态变化。

Redux 核心概念

在学习 Redux 之前,让我们先来介绍一些它的核心概念。

1. Store

Redux 中一切都从 store 开始。Store 实际上只是将 reducer 和当前状态存储在一起的对象。它暴露了一些方法(dispatch、getState 和 subscribe),我们可以调用这些方法来访问内部结构。

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

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

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

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

2. Action

在 Redux 中进行任何更改都要依靠 action。Action 是一个普通的 JS 对象,它描述了一种要执行的行为。Action 必须包含一个 type 字段,来描述这个行为是什么。我们可以在 type 字段中使用字符串。除了 type 之外,它可以包含其他属性,尽管 Redux 并不会强制执行这一点。

3. Reducers

Reducer 是一个纯函数,接收一个当前状态和 action 对象,返回一个新的状态对象。Reducer 必须是纯函数,它不能修改 input 值,而且每次调用都必须返回一个新的对象。对 state 进行任何修改的操作都会返回一个全新的对象。

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

4. Dispatch

store 提供了 dispatch 方法,该方法接受一个 action 作为参数,由于 reducer 是通过 action 来执行的,所以 store 会把它发送给 reducer,从而更新状态。

当我们在调用 dispatch 方法的时候,store 会执行 reducer 函数,并将其存储在 store 内部的状态中。这时,store 将通知所有侦听器(subscribe 方法注册的函数),以便他们可以检索新的状态并更新用户界面。

5. Subscribe

使用 subscribe 方法可以一直监听 store 状态的变化,当 store 状态变化时就会自动执行注册的函数。

在 React 中使用 Redux

让我们现在来看看如何在 React 中使用 Redux。在 React 中,我们可以将 Redux Store 作为上下文传递给所有的子组件,这样无论在哪个组件中访问 store,我们都不需要手动传递它。

首先,我们需要创建一个 Redux Store 并将其嵌套在 parent 组件中,其他所有的组件都可以访问顶层 store。

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

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

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

这里要注意到的是,我们首先需要将 rootReducer 作为 createStore() 的参数。rootReducer 是一个庞大的对象,它包含了应用程序状态的所有不同部分,并且每个部分都由相应的 reducer 处理。使用 combineReducer 函数可以创建 rootReducer:

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

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

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

在完成了以上操作后,我们就可以在 React 应用程序中使用 store。下面我们来具体演示如何在组件中使用 store。

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

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

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

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

在上面的代码中,我们采用了 react-redux 提供的 connect 高阶组件。mapStateToProps 函数作为 connect 的第一个参数,它将 Redux Store 中的状态映射到组件的 props 属性。通过访问 this.props.count,我们可以在组件中获取处理 store 中的 数量 count。

connected 组件(即从组件调用 connect 方法得到的新组件)会自动订阅任何与 Redux Store 相关的更新。如果 Store 更新了,connect 会触发子组件的重新渲染。

现在,每当我们更新 store 中的数量时,组件就会重新渲染。我们可以通过调用 store.dispatch() 函数来执行更新(例如,通过按下按钮)。不过更好的做法是通过 connect 将 dispatch 与组件相结合:

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

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

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

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

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

在上面的代码中,我们传递了 mapDispatchToProps 属性给 connect 方法。它映射出一个名为 increment 的函数,该函数向 store 分派一个事件,该事件会触发 reducer 函数并更新 store。

结论

至此,我们已经详细学习了如何在 React 组件中实现自身的全局状态管理,并使用 Redux 库作为状态管理工具。通过加强对 Redux 的理解,我们可以改善 React 应用程序的可维护性,从而让代码更易于维护和扩展。当我们的应用程序需要共享状态或具有多个嵌套组件时,Redux 提供了一种完整且可靠的状态管理解决方案,从而让我们写出更简洁、更可维护的代码。

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

纠错
反馈