前端 MobX 与 Redux 的差异与选择

06-01 1065阅读

前端 MobX 与 Redux 的差异与选择

关键词:前端开发、MobX、Redux、状态管理、差异、选择

摘要:在前端开发中,状态管理是一个重要的话题。MobX 和 Redux 是两种常用的状态管理库,它们各有特点。本文将深入探讨 MobX 和 Redux 的核心概念、工作原理、差异以及在不同场景下的选择,帮助开发者更好地理解和运用这两种工具,提升前端开发的效率和质量。

背景介绍

目的和范围

在前端开发里,随着应用复杂度的增加,状态管理变得越来越重要。我们的目的就是要搞清楚 MobX 和 Redux 这两个状态管理库的不同之处,以及在什么情况下该选择哪一个。这篇文章的范围会涵盖它们的核心概念、工作原理、实际应用等方面。

预期读者

这篇文章主要是给前端开发者看的,不管你是刚入门的新手,还是有一定经验的开发者,都能从这里面学到有用的知识,帮助你在实际开发中做出更好的选择。

文档结构概述

接下来,我们会先介绍 MobX 和 Redux 的核心概念,然后分析它们之间的差异,再通过实际的代码案例展示它们的使用方法,接着探讨它们的实际应用场景,最后总结一下该如何选择这两个库,还会留下一些思考题让大家进一步思考。

术语表

核心术语定义
  • 状态管理:在前端开发中,状态就是应用的数据。状态管理就是对这些数据进行有效的组织、存储和更新,让应用能够正常运行。
  • 可观察性:简单来说,就是当数据发生变化时,系统能够自动感知到这种变化,并做出相应的反应。
  • 单向数据流:数据的流动是单向的,从一个方向流向另一个方向,这样可以让数据的流向更加清晰,便于管理。
    相关概念解释
    • 响应式编程:当数据发生变化时,相关的部分会自动更新,就像你在玩多米诺骨牌,推倒一个,后面的就会依次倒下。
    • 纯函数:一个函数,只要输入相同,输出就一定相同,而且不会对外部环境产生任何副作用。
      缩略词列表
      • UI:用户界面,就是我们在浏览器里看到的页面。

        核心概念与联系

        故事引入

        想象一下,你是一个大型超市的管理员。超市里有各种各样的商品,这些商品的库存数量就是超市的“状态”。每天都会有顾客来买东西,也会有新的货物进货,这就相当于状态的变化。你需要一种方法来管理这些库存信息,让自己随时知道每种商品还剩多少。

        现在有两种管理库存的方法。一种方法是,你给每个商品都贴上一个特殊的标签,这个标签会自动记录商品的数量变化,只要数量一改变,标签就会发光提醒你。这就有点像 MobX 的工作方式。另一种方法是,你有一个专门的账本,每次商品数量有变化,都要严格按照一定的步骤在账本上记录下来,所有的变化都要通过这个账本进行管理。这就类似于 Redux 的工作方式。

        核心概念解释(像给小学生讲故事一样)

        核心概念一:MobX

        MobX 就像是一个超级智能的管家。在我们的超市里,每个商品都有一个特殊的标签,这个标签就是 MobX 的“可观察对象”。当商品的数量发生变化时,这个标签会自动感知到,然后通知相关的人员(比如收银员、补货员)。收银员看到标签发光,就知道商品数量变了,要更新收银系统;补货员看到标签发光,就知道该去补货了。

        核心概念二:Redux

        Redux 就像是一个严格的会计。在超市里,有一个专门的账本,这个账本就是 Redux 的“store”。每次商品数量有变化,都要写一张“纸条”(action),上面写清楚是哪种商品,数量是增加还是减少。然后把这张纸条交给会计(reducer),会计会根据纸条上的信息在账本上进行记录。所有的库存信息都要通过这个账本进行管理。

        核心概念三:状态管理

        状态管理就像是给超市的库存信息建一个“家”。在前端开发中,应用的数据就是状态,我们要把这些数据好好地组织起来,让它们有一个固定的地方存放,并且能够方便地进行读取和更新。就像超市里的商品要分类摆放,并且有一个库存记录系统一样。

        核心概念之间的关系(用小学生能理解的比喻)

        概念一和概念二的关系:

        MobX 和 Redux 就像是两个不同风格的管家。MobX 比较灵活,它就像一个随时都在观察商品变化的管家,一有风吹草动就马上做出反应。而 Redux 比较严谨,它就像一个严格按照规则办事的管家,所有的变化都要通过特定的流程来处理。

        概念二和概念三的关系:

        Redux 是状态管理的一种实现方式。就像超市的会计账本是管理库存信息的一种方式一样。Redux 通过 store 来存储状态,通过 action 和 reducer 来管理状态的变化,让状态管理变得更加有条理。

        概念一和概念三的关系:

        MobX 也是状态管理的一种实现方式。它通过可观察对象来跟踪状态的变化,当状态发生变化时,自动更新相关的组件。就像超市里的特殊标签,能够自动感知商品数量的变化,并通知相关人员。

        核心概念原理和架构的文本示意图

        MobX

        MobX 的核心是可观察对象(observable)。可观察对象是一种特殊的数据结构,它能够自动跟踪数据的变化。当可观察对象的数据发生变化时,与之相关的计算值(computed)和反应(reaction)会自动更新。计算值是根据可观察对象计算出来的结果,反应则是当可观察对象变化时执行的副作用操作,比如更新 UI。

        Redux

        Redux 的核心是 store。store 是一个单一的对象,它存储了应用的所有状态。action 是一个描述状态变化的对象,reducer 是一个纯函数,它接收当前的状态和 action,返回一个新的状态。当有 action 被触发时,reducer 会根据 action 的类型和数据更新 store 中的状态。

        前端 MobX 与 Redux 的差异与选择
        (图片来源网络,侵删)

        Mermaid 流程图

        MobX 流程图
        Redux 流程图

        核心算法原理 & 具体操作步骤

        MobX 核心算法原理及操作步骤

        原理

        MobX 的核心原理是基于响应式编程。它通过可观察对象来跟踪数据的变化,当可观察对象的数据发生变化时,会自动通知所有依赖于这个可观察对象的计算值和反应。

        操作步骤
        1. 定义可观察对象:在 MobX 中,我们可以使用 makeObservable 或 makeAutoObservable 函数来定义可观察对象。
        import { makeAutoObservable } from 'mobx';
        class Store {
            constructor() {
                // 定义一个可观察的状态
                this.counter = 0;
                makeAutoObservable(this);
            }
            // 定义一个动作,用于改变状态
            increment() {
                this.counter++;
            }
        }
        const store = new Store();
        
        1. 创建计算值:计算值是根据可观察对象计算出来的结果,当可观察对象发生变化时,计算值会自动更新。
        import { makeAutoObservable, computed } from 'mobx';
        class Store {
            constructor() {
                this.counter = 0;
                makeAutoObservable(this);
            }
            increment() {
                this.counter++;
            }
            // 定义一个计算值
            get doubleCounter() {
                return this.counter * 2;
            }
        }
        const store = new Store();
        
        1. 创建反应:反应是当可观察对象变化时执行的副作用操作,比如更新 UI。在 React 中,我们可以使用 observer 高阶组件来创建反应。
        import React from 'react';
        import { observer } from 'mobx-react';
        import { makeAutoObservable } from 'mobx';
        class Store {
            constructor() {
                this.counter = 0;
                makeAutoObservable(this);
            }
            increment() {
                this.counter++;
            }
        }
        const store = new Store();
        const CounterComponent = observer(() => {
            return (
                
                    

        Counter: {store.counter}

        前端 MobX 与 Redux 的差异与选择
        (图片来源网络,侵删)
        store.increment()}>Increment ); }); export default CounterComponent;

        Redux 核心算法原理及操作步骤

        原理

        Redux 的核心原理是单向数据流。所有的状态都存储在一个单一的 store 中,action 是描述状态变化的对象,reducer 是一个纯函数,它接收当前的状态和 action,返回一个新的状态。当有 action 被触发时,reducer 会根据 action 的类型和数据更新 store 中的状态。

        操作步骤
        1. 定义 action:action 是一个描述状态变化的对象,它必须有一个 type 属性。
        // 定义一个 action 类型
        const INCREMENT = 'INCREMENT';
        // 定义一个 action 创建函数
        function increment() {
            return {
                type: INCREMENT
            };
        }
        
        1. 定义 reducer:reducer 是一个纯函数,它接收当前的状态和 action,返回一个新的状态。
        // 定义初始状态
        const initialState = {
            counter: 0
        };
        // 定义 reducer
        function counterReducer(state = initialState, action) {
            switch (action.type) {
                case INCREMENT:
                    return {
                        ...state,
                        counter: state.counter + 1
                    };
                default:
                    return state;
            }
        }
        
        1. 创建 store:使用 createStore 函数创建一个 store。
        import { createStore } from 'redux';
        // 创建 store
        const store = createStore(counterReducer);
        
        1. 触发 action:使用 dispatch 方法触发 action。
        // 触发 action
        store.dispatch(increment());
        
        1. 订阅 store 的变化:使用 subscribe 方法订阅 store 的变化,当 store 中的状态发生变化时,会执行回调函数。
        // 订阅 store 的变化
        store.subscribe(() => {
            console.log(store.getState());
        });
        
        1. 在 React 中使用 Redux:使用 react-redux 库将 Redux 与 React 集成。
        import React from 'react';
        import { Provider } from 'react-redux';
        import { createStore } from 'redux';
        import { connect } from 'react-redux';
        // 定义 action 和 reducer
        const INCREMENT = 'INCREMENT';
        function increment() {
            return {
                type: INCREMENT
            };
        }
        const initialState = {
            counter: 0
        };
        function counterReducer(state = initialState, action) {
            switch (action.type) {
                case INCREMENT:
                    return {
                        ...state,
                        counter: state.counter + 1
                    };
                default:
                    return state;
            }
        }
        // 创建 store
        const store = createStore(counterReducer);
        // 定义组件
        const CounterComponent = ({ counter, increment }) => {
            return (
                
                    

        Counter: {counter}

        前端 MobX 与 Redux 的差异与选择
        (图片来源网络,侵删)
        Increment ); }; // 连接组件和 store const mapStateToProps = (state) => { return { counter: state.counter }; }; const mapDispatchToProps = (dispatch) => { return { increment: () => dispatch(increment()) }; }; const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(CounterComponent); // 在应用中使用 Provider 提供 store const App = () => { return ( ); }; export default App;

        数学模型和公式 & 详细讲解 & 举例说明

        MobX

        在 MobX 中,没有严格意义上的数学模型和公式。但是我们可以用一个简单的例子来说明它的工作原理。假设我们有一个可观察对象 x,一个计算值 y 是 x 的两倍,即 y = 2 x y = 2x y=2x。当 x 的值发生变化时,y 的值会自动更新。

        import { makeAutoObservable, computed } from 'mobx';
        class Store {
            constructor() {
                this.x = 1;
                makeAutoObservable(this);
            }
            get y() {
                return this.x * 2;
            }
        }
        const store = new Store();
        console.log(store.y); // 输出 2
        store.x = 2;
        console.log(store.y); // 输出 4
        

        Redux

        Redux 的核心可以用一个简单的公式来表示: s t a t e n e w = r e d u c e r ( s t a t e o l d , a c t i o n ) state_{new} = reducer(state_{old}, action) statenew​=reducer(stateold​,action)。其中, s t a t e o l d state_{old} stateold​ 是当前的状态, a c t i o n action action 是描述状态变化的对象, r e d u c e r reducer reducer 是一个纯函数,它接收当前的状态和 action,返回一个新的状态 s t a t e n e w state_{new} statenew​。

        例如,我们有一个简单的计数器应用,初始状态是 s t a t e o l d = c o u n t e r : 0 state_{old} = { counter: 0 } stateold​=counter:0,当触发一个 INCREMENT action 时,reducer 会根据这个 action 更新状态。

        const INCREMENT = 'INCREMENT';
        function increment() {
            return {
                type: INCREMENT
            };
        }
        const initialState = {
            counter: 0
        };
        function counterReducer(state = initialState, action) {
            switch (action.type) {
                case INCREMENT:
                    return {
                        ...state,
                        counter: state.counter + 1
                    };
                default:
                    return state;
            }
        }
        const oldState = { counter: 0 };
        const action = increment();
        const newState = counterReducer(oldState, action);
        console.log(newState); // 输出 { counter: 1 }
        

        项目实战:代码实际案例和详细解释说明

        开发环境搭建

        MobX
        1. 创建一个新的 React 项目:
        npx create-react-app mobx-example
        cd mobx-example
        
        1. 安装 MobX 和 MobX React:
        npm install mobx mobx-react
        
        Redux
        1. 创建一个新的 React 项目:
        npx create-react-app redux-example
        cd redux-example
        
        1. 安装 Redux 和 React Redux:
        npm install redux react-redux
        

        源代码详细实现和代码解读

        MobX 项目实战
        import React from 'react';
        import { observer } from 'mobx-react';
        import { makeAutoObservable } from 'mobx';
        // 定义 Store 类
        class Store {
            constructor() {
                // 定义可观察的状态
                this.counter = 0;
                // 自动将所有属性和方法转换为可观察的
                makeAutoObservable(this);
            }
            // 定义一个动作,用于增加计数器的值
            increment() {
                this.counter++;
            }
        }
        // 创建 Store 实例
        const store = new Store();
        // 定义一个使用 MobX 的组件
        const CounterComponent = observer(() => {
            return (
                
                    

        Counter: {store.counter}

        store.increment()}>Increment ); }); // 定义 App 组件 const App = () => { return ( ); }; export default App;

        代码解读:

        • Store 类:定义了一个可观察的状态 counter 和一个动作 increment。makeAutoObservable 函数将 counter 转换为可观察对象,当 counter 的值发生变化时,会自动通知所有依赖于它的组件。
        • CounterComponent:使用 observer 高阶组件将组件转换为响应式组件,当 store.counter 的值发生变化时,组件会自动重新渲染。
        • App 组件:渲染 CounterComponent。
          Redux 项目实战
          import React from 'react';
          import { Provider } from 'react-redux';
          import { createStore } from 'redux';
          import { connect } from 'react-redux';
          // 定义 action 类型
          const INCREMENT = 'INCREMENT';
          // 定义 action 创建函数
          function increment() {
              return {
                  type: INCREMENT
              };
          }
          // 定义初始状态
          const initialState = {
              counter: 0
          };
          // 定义 reducer
          function counterReducer(state = initialState, action) {
              switch (action.type) {
                  case INCREMENT:
                      return {
                          ...state,
                          counter: state.counter + 1
                      };
                  default:
                      return state;
              }
          }
          // 创建 store
          const store = createStore(counterReducer);
          // 定义组件
          const CounterComponent = ({ counter, increment }) => {
              return (
                  
                      

          Counter: {counter}

          Increment ); }; // 连接组件和 store const mapStateToProps = (state) => { return { counter: state.counter }; }; const mapDispatchToProps = (dispatch) => { return { increment: () => dispatch(increment()) }; }; const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(CounterComponent); // 定义 App 组件 const App = () => { return ( ); }; export default App;

          代码解读:

          • action:定义了一个 INCREMENT 类型的 action 和一个 action 创建函数 increment。
          • reducer:定义了一个纯函数 counterReducer,它接收当前的状态和 action,返回一个新的状态。
          • store:使用 createStore 函数创建一个 store,将 counterReducer 作为参数传入。
          • CounterComponent:定义了一个普通的 React 组件,接收 counter 和 increment 作为 props。
          • mapStateToProps 和 mapDispatchToProps:分别将 store 中的状态和 action 映射到组件的 props 上。
          • connect:使用 connect 函数将 CounterComponent 连接到 store,返回一个新的组件 ConnectedCounter。
          • App 组件:使用 Provider 组件将 store 提供给整个应用。

            代码解读与分析

            MobX
            • 优点:
              • 代码简洁:不需要定义大量的 action 和 reducer,只需要定义可观察对象和动作即可。
              • 开发效率高:由于是自动跟踪状态变化,开发人员可以更专注于业务逻辑。
              • 缺点:
                • 调试困难:由于状态变化是自动触发的,调试时可能会比较困难。
                • 难以理解:对于初学者来说,响应式编程的概念可能比较难以理解。
                  Redux
                  • 优点:
                    • 可预测性强:由于采用了单向数据流和纯函数的 reducer,状态的变化是可预测的,便于调试和维护。
                    • 易于测试:reducer 是纯函数,易于编写单元测试。
                    • 缺点:
                      • 代码冗余:需要定义大量的 action 和 reducer,代码量会比较大。
                      • 开发效率低:由于需要遵循严格的流程,开发效率可能会受到一定的影响。

                        实际应用场景

                        MobX

                        • 小型项目:对于小型项目,状态管理的复杂度较低,使用 MobX 可以快速实现功能,提高开发效率。
                        • 实时数据更新:当应用需要实时更新数据时,MobX 的响应式编程可以很好地满足需求。例如,实时聊天应用、股票行情应用等。
                        • 灵活的状态管理:如果应用的状态管理比较灵活,不需要严格的单向数据流,使用 MobX 可以更加方便。

                          Redux

                          • 大型项目:对于大型项目,状态管理的复杂度较高,使用 Redux 可以更好地组织代码,提高代码的可维护性。
                          • 多人协作开发:由于 Redux 的单向数据流和严格的流程,多人协作开发时可以避免状态管理的混乱。
                          • 需要时间旅行调试的场景:Redux 支持时间旅行调试,可以方便地查看状态的历史变化,对于调试复杂的应用非常有帮助。

                            工具和资源推荐

                            MobX

                            • MobX 官方文档:https://mobx.js.org/ ,提供了详细的文档和教程。
                            • MobX React:https://github.com/mobxjs/mobx-react ,用于在 React 中使用 MobX 的库。
                            • MobX DevTools:https://github.com/mobxjs/mobx-devtools ,用于调试 MobX 应用的工具。

                              Redux

                              • Redux 官方文档:https://redux.js.org/ ,提供了详细的文档和教程。
                              • React Redux:https://github.com/reduxjs/react-redux ,用于在 React 中使用 Redux 的库。
                              • Redux DevTools:https://github.com/reduxjs/redux-devtools ,用于调试 Redux 应用的工具。

                                未来发展趋势与挑战

                                MobX

                                发展趋势
                                • 与新技术的结合:随着前端技术的不断发展,MobX 可能会与更多的新技术结合,如 React Hooks、WebAssembly 等,提供更强大的功能。
                                • 移动端应用:在移动端应用开发中,MobX 的轻量级和高开发效率可能会受到更多的关注。
                                  挑战
                                  • 生态系统的完善:相比 Redux,MobX 的生态系统还不够完善,需要进一步发展和完善。
                                  • 性能优化:在处理大量数据和复杂场景时,MobX 的性能可能会受到一定的影响,需要进行性能优化。

                                    Redux

                                    发展趋势
                                    • 标准化和规范化:Redux 的单向数据流和严格的流程符合软件开发的标准化和规范化趋势,未来可能会在更多的项目中得到应用。
                                    • 与微前端的结合:随着微前端架构的发展,Redux 可以用于管理多个微前端应用之间的状态,提高应用的可维护性。
                                      挑战
                                      • 学习成本:Redux 的概念和流程相对复杂,对于初学者来说,学习成本较高。
                                      • 代码复杂度:在处理复杂的状态管理时,Redux 的代码会变得非常复杂,需要进一步优化和简化。

                                        总结:学到了什么?

                                        核心概念回顾

                                        • MobX:是一个基于响应式编程的状态管理库,通过可观察对象来跟踪状态的变化,自动更新相关的计算值和反应。
                                        • Redux:是一个采用单向数据流的状态管理库,通过 store、action 和 reducer 来管理状态的变化。
                                        • 状态管理:是对应用的数据进行有效组织、存储和更新的过程。

                                          概念关系回顾

                                          • MobX 和 Redux 都是状态管理的实现方式,它们的目的都是为了更好地管理应用的状态。
                                          • MobX 比较灵活,适合小型项目和实时数据更新的场景;Redux 比较严谨,适合大型项目和多人协作开发的场景。

                                            思考题:动动小脑筋

                                            思考题一

                                            在一个实时聊天应用中,应该选择 MobX 还是 Redux 来管理状态?为什么?

                                            思考题二

                                            如果你要开发一个大型的电商应用,状态管理会涉及到商品列表、购物车、用户信息等多个方面,你会选择 MobX 还是 Redux?如何进行状态管理的设计?

                                            附录:常见问题与解答

                                            MobX 问题解答

                                            • 问:MobX 的可观察对象和普通对象有什么区别?

                                              答:可观察对象是 MobX 中的特殊对象,它能够自动跟踪数据的变化,并通知所有依赖于它的计算值和反应。普通对象则没有这种功能。

                                            • 问:在 MobX 中,如何避免无限循环更新?

                                              答:可以使用 autorun 或 reaction 函数的配置选项来控制更新的频率,避免无限循环更新。

                                              Redux 问题解答

                                              • 问:Redux 中的 reducer 为什么必须是纯函数?

                                                答:纯函数具有可预测性,只要输入相同,输出就一定相同,而且不会对外部环境产生任何副作用。这样可以保证状态的变化是可预测的,便于调试和维护。

                                              • 问:在 Redux 中,如何处理异步操作?

                                                答:可以使用中间件,如 redux-thunk 或 redux-promise 来处理异步操作。这些中间件可以让 action 创建函数返回一个函数或 Promise,从而处理异步逻辑。

                                                扩展阅读 & 参考资料

                                                • 《React 状态管理与同构实战》
                                                • 《深入浅出 React 和 Redux》
                                                • MobX 官方文档:https://mobx.js.org/
                                                • Redux 官方文档:https://redux.js.org/
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码