Redux 和 MobX 的面向对象与函数式设计思路

阅读时长 7 分钟读完

Redux 和 MobX 是目前前端最流行的状态管理库,根据个人偏好和项目需求可以选择使用其中一种或同时使用。Redux 和 MobX 虽然有不同的语法和实现方式,但是它们都融合了面向对象和函数式编程的思想,让我们来深入了解一下它们的设计思路。

Redux

函数式编程思路

Redux 的核心是纯函数,所谓纯函数就是相同的输入一定会得到相同的输出,而且不会有副作用。Redux 中的 reducer 函数就是一个纯函数,它接收两个参数 stateaction,返回一个新的状态。

下面是一个简单的 Redux 应用程序,它有两个动作 incrementdecrement,分别用于增加和减少计数器的值。

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

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

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

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

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

在这个例子中,counterReducer 函数是一个纯函数,它根据传入的 stateaction 返回一个新的状态。createStore 函数创建了一个 Redux store,并将 counterReducer 函数传入其中。store.dispatch 方法用于派发动作,并且会自动调用 counterReducer 函数来更新状态。store.getState 方法用于获取当前的状态。

Redux 还提供了许多中间件,比如说 redux-thunkredux-saga 用于异步流程控制,以及 redux-logger 用于记录状态变更日志。这些中间件都是基于函数式编程思想实现的,让代码变得更加优美和可读。

面向对象编程思路

虽然 Redux 的核心是纯函数,但是它依然借鉴了面向对象编程的一些思想。Redux 中的状态就像是一个全局变量,而且它可以随时被修改。为了避免意外修改状态,Redux 引入了一个名为 action 的概念,用于描述对状态进行的修改操作。每个 action 都需要包含一个 type 属性,用于描述这个操作的种类,以及一些可选的参数。此外,Redux 还支持 action creator,它是一个函数,用于返回一个 action 对象,方便用户使用。

下面是一个使用 actionaction creator 的例子。

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

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

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

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

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

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

在这个例子中,我们定义了一个 action creator 函数 addTodoAction,用于返回一个 ADD_TODO 类型的 action 对象,并且包含一些附加信息。在 todoReducer 函数中,我们检查了 actiontype 属性,根据不同的操作进行状态更新。最后通过 createStore 函数创建了一个 Redux store,并且使用 store.dispatch 方法派发了一个 action

MobX

面向对象编程思路

与 Redux 不同,MobX 基于观察者模式,将状态视为一个可观察对象,任何修改状态的操作都会通知观察者。这个观察者可以是界面层,也可以是其他部分的代码,这种方式让开发变得更加直观。

下面是一个简单的 MobX 应用程序,它有两个动作 incrementdecrement,分别用于增加和减少计数器的值。

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

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

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

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

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

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

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

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

在这个例子中,我们定义了一个名为 Counter 的类,用于表示计数器状态。使用 makeAutoObservable 方法可以将 Counter 类中的所有属性和方法都转换为可观察对象,并且自动创建了 action 方法。在 incrementdecrement 方法中,我们直接修改了 count 属性的值,这会自动触发界面层的更新。

函数式编程思路

MobX 可能更加偏向于面向对象编程,但是它也支持一些函数式编程思想,比如说响应式编程和函数式管道。响应式编程是指在程序中引入响应式数据流,当数据发生变化时,相应的处理流程会被自动触发。MobX 正是基于这个思想建立的,它可以让我们更加专注于数据本身,而不是如何更新它。

下面是一个使用函数式管道的例子,它将一个数组中的数据进行排序和筛选,并且返回前两个结果。

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

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

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

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

在这个例子中,我们使用 observable 方法创建了一个可观察的数据源 data,其中包含了几个人的信息。接着,我们使用 computed 方法创建了一个计算属性 sortedData,它会对 data 进行排序和筛选操作,并且返回前两个结果。computed 方法会自动缓存计算结果,只有在需要更新的时候才会重新计算。

总结

Redux 和 MobX 都是优秀的状态管理库,它们都兼容了面向对象和函数式编程的思想。Redux 将状态的修改操作抽象成了一个纯函数,使得状态更新变得可预测和可测试,而 MobX 则让我们更加关注数据本身,而不必过多地担心如何更新它。我们应该根据自己的项目需求和个人偏好来选择使用一个或者多个库,并且深入了解它们的设计思路和使用方法,以达到更加优秀的开发效果。

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

纠错
反馈