❝ 本文整理下近期 redux、mobx 在 react 中的使用对比,大家可以根据个人喜好,合理使用
查看完整 demo

redux 状态管理

redux 基本使用流程

❝ 首先把 redux 的基本使用步骤梳理一下

  1. createStore 创建状态集合 store,初始化的时候参数是相关的 reducer 以及 middleware,下面将具体说明
import { createStore, combineReducers, applyMiddleware } from "redux";
// 初始化状态集合
const store = createStore(// 合并 reducercombineReducers({ counter: counterReducer, other: otherReducer }),// 引入中间件applyMiddleware(logger)
);

  1. react-redux 中的 Provider 组件接收创建的 store,并置于组件顶层
import { render } from "react-dom";
import { Provider } from "react-redux";render(<Provider store={store}><App /></Provider>,document.getElementById("app")
);

  1. 定义 reducer 自定义行为与处理的 state
// 初始 state
const INITIAL_STATE = {step: 0,
};// 抽离对外暴露的行为枚举
export const counterActionEnum = {step: "step",reset: "reset",
};// 定义 reducer 不同行为下的不同 state 处理
export default function counterReducer(state = INITIAL_STATE, action) {console.log("reducer@", state, action, INITIAL_STATE);switch (action.type) {case counterActionEnum.step:return {step: state.step + 1,};case counterActionEnum.reset:return {...INITIAL_STATE,};default:return state;}
}

  1. connect 链接 reducer 参与业务衔接,暴露 storedispatch 到相关业务组件中
import React from "react";
import { connect } from "react-redux";
import { counterActionEnum } from "../reducers/counter";function Counter(props) {const { counter, doStep, doReset } = props;return (<div><span>计步器:{counter.step}</span><button onClick={() => doStep()}>计步</button><button onClick={() => doReset()}>重置</button></div>);
}// 链接 reducer 与 Counter
export default connect(// mapStateToProps 将 state 映射到组件的 props 中(state) => ({ counter: state.counter }),// mapDispatchToProps 将 dispatch 转发后的 action 映射到组件的 props 中(dispatch) => ({// 通过 dispatch 触发行为doStep: () => dispatch({ type: counterActionEnum.step }),doReset: () => dispatch({ type: counterActionEnum.reset }),})
)(Counter);

redux 数据流

❝ 下图可以形象的说明 redux 在数据中的流程表现:
connect -> Component -> dispatch action -> store -> mapStateToProps -> Component update

引入 redux 中间件

❝ 这里思考下 redux 中间件的意义:

  1. 为什么需要有中间件机制?
  2. 中间件具体在数据流中如何体现?
  3. 中间件有哪些应用场景?

自定义中间件

❝ 这里我们先手写一下中间件看看它具体处于数据流的哪一步?

// 自定义中间件规则
const logger = ({ dispatch, getState }) => (next) => (action) => {console.log("[logger before]:", action);// 执行下一个 dispatchconst result = next(action);console.log("[logger after]:", action, getState());return result;
};// ...
// 初始化 store 时引入 logger middleware
const store = createStore(// 合并 reducercombineReducers({ counter: counterReducer, other: otherReducer }),// 引入中间件applyMiddleware(logger)
);

❝ 引入中间件后执行一个 action 的打印结果如下:

[logger before]: {type: "step"}
// dispatch action
reducer@ {step: 0} {type: "step"} {step: 0}
[logger after]: {type: "step"} {counter: {…}}

❝ 以上打印可以看出 middleware 的可以劫持 dispatch action 向下执行,以此可以看出中间件的重大作用,可以穿插于 action 数据流走向:

  1. 比如我想在每次 dispatch action 前后做些什么;
  2. 比如我又想劫持某些 action 做些什么,这个时候也比较方便;
  3. 再比如我想实现异步的 action 也可以在这一步去做劫持;

由此可见,redux middleware 意义重大

redux 异步 action

  1. 我们看一下 redux-thunk 的源码,通过劫持 action 来扩展异步

❝ 其实 redux-thunk 的思路比较简单,劫持了 action function 的扩展

function createThunkMiddleware(extraArgument) {return ({ dispatch, getState }) => (next) => (action) => {// 劫持 action,对 action 提供了扩展,在扩展中自己去实现异步if (typeof action === "function") {return action(dispatch, getState, extraArgument);}return next(action);};
}const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;export default thunk;

  1. 简单来说,其实通过 mapDispatchToProps 中自己异步执行 dispatch 即可
function mapDispatchToProps(dispatch) {return {// 通过 dispatch 触发行为doStep: () => {// 1s 后执行 actionsetTimeout(() => {dispatch({ type: counterActionEnum.step });}, 1000);},doReset: () => dispatch({ type: counterActionEnum.reset }),};
}

mobx 状态管理

mobx 基本使用流程

  1. 创建一个 store

❝ 定义一个 class,使用注解 @observable 使值可响应,使用 @action 定义响应方法

import { observable, action } from "mobx";class CounterStore {@observable step = 0;@actiondoStep = () => {this.step++;};@actiondoReset = () => {this.step = 0;};
}// 抛出一个实例
export default new CounterStore();

  1. Provider 引入 counterStore

❝ 所有的 store 都在顶层通过 Provider 混入到全局

<Provider counterStore={counterStore}><div><h1>mobx 计步器</h1><CounterApp /></div>
</Provider>

  1. inject 将需要的状态混入到组件的 props,并通过 observer 使组件可响应
// 将 counterStore 混入到 Counter 的 props 中
const CounterApp = inject("counterStore")(observer(Counter));

  1. 组件中调用对应的 state 与 action
function Counter({ counterStore }) {const { step, doStep, doReset } = counterStore;return (<div><span>计步器:{step}</span>{"  "}<button onClick={() => doStep()}>计步</button>{"  "}<button onClick={() => doReset()}>重置</button></div>);
}

mobx 数据流

❝ mobx 的思路比较简单,通过 action -> state -> view,下图明确提现了 mobx 的数据交互流程

总结

redux 优点

  1. 流程规范,按照官方推荐的规范和结合团队风格打造一套属于自己的流程。
  2. 函数式编程,在 reducer 中,接受输入,然后输出,不会有副作用发生,幂等性。
  3. 可追踪性,很容易追踪产生 BUG 的原因。

redux 缺点

  1. 流畅太繁琐,需要写各种 type、action、reducer,不易上手,初学者可能会觉得比较绕。
  2. 同步数据流,异步需要引用其他库(redux-thunk/redux-saga 等)或者通过异步 dispatch 的技巧。

mobx 优点

  1. 容易上手,class 中管理 state、action,使用简单,基于 Proxy 实现的数据响应式。
  2. 写更少的代码,完成更多的事。不会跟 redux 一样写非常多的 action、type。
  3. 使组件更加颗粒化拆分,并且业务更加容易抽象。

mobx 缺点

  1. 过于自由,mobx 提供的约定及模版代码很少,如果团队不做一些约定,容易导致团队代码风格不统一。

往期文章

  1. 面试让你造轮子,不会就很尴尬了(new/apply/call....)
  2. 如何实现一个通过 Promise/A+ 规范的 Promise
  3. 基于 Proxy 实现简易版 Vue
  4. 从源码层面解读 16 道 Vue 常考面试题
  5. 32 道面试题详解,看看有你想要的吗?
  6. 基于 jsx 语法手写实现简易版 react

react dispatch_梳理下redux、mobx 在react的应用相关推荐

  1. [Redux/Mobx] 在React中你是怎么对异步方案进行选型的?

    [Redux/Mobx] 在React中你是怎么对异步方案进行选型的? 小项目使用简单的redux-thunk方案,增加的代码量极少,只有两个api,上手成本低 大项目使用基于redux-saga的d ...

  2. [react] 简要描述下你知道的react工作原理是什么?

    [react] 简要描述下你知道的react工作原理是什么? 我理解的核心部分: 通过虚拟DOM表达真实DOM 通过数据驱动更新虚拟DOM进而更新真实DOM(MVVM) 有一套完整并且合理的 DOM ...

  3. mobx在react中应用_借助React Native Elements,Jest和MobX MST可以轻松实现现实世界中的ReactNative应用...

    mobx在react中应用 by Qaiser Abbas 由Qaiser Abbas 借助React Native Elements,Jest和MobX MST可以轻松实现现实世界中的ReactNa ...

  4. Redux/Mobx面试题汇总

    [Redux/Mobx] redux和flux的区别是什么? [Redux/Mobx] 什么是redux?说说你对redux的理解?有哪些运用场景? [Redux/Mobx] 在React中你是怎么对 ...

  5. React中的状态管理---Mobx

    Mobx的介绍 Mobx是一个功能强大,上手非常容易的状态管理工具.redux的作者也曾经向大家推荐过它,在不少情况下可以使用Mobx来替代掉redux. Mobx流程图 Mobx使用流程 创建项目 ...

  6. React技术栈探究-Redux

    React技术栈耕耘 -- Redux Redux 是近年来提出的 Flux 思想的一种实践方案,在它之前也有 reflux . fluxxor 等高质量的作品,但短短几个月就在 GitHub 上获近 ...

  7. mobx在react如何使用

    这边文章主要目的呢.是搭建一个react和mobx的demo.能够了解mobx在react应用中如何使用的.我会用大白话的形式写这个文章: 文末有react 和react-native 的两个集成mo ...

  8. 这是可用于下一个项目的React Native工具列表

    by Rajput Mehul 通过拉杰普特·梅胡尔(Rajput Mehul) 这是可用于下一个项目的React Native工具列表 (Here's a list of React Native ...

  9. 【转】浅谈React、Flux 与 Redux

    本文转自<浅谈React.Flux 与 Redux>,转载请注明出处. React React 是一个 View 层的框架,用来渲染视图,它主要做几件事情: 组件化 利用 props 形成 ...

最新文章

  1. Linux rpm 命令参数
  2. 集成 jpush-react-native 常见问题汇总 ( iOS 篇)
  3. 使用jasmine.createSpyObj具有依赖关系的Angular服务进行单元测试
  4. Zookeeper java客户端ZkClient使用详解
  5. mysql三高讲解(一):1.2 一个sql语句的执行过程
  6. 随想录(关于核心技术)
  7. python异常处理知识点_一文掌握 Python 异常处理的所有知识点
  8. 响应式网站设计 - 最佳实践
  9. 1.多线程和单线程简单比较
  10. 2020年php发卡源码,2020年最新PHP自动化售货发卡网源码带教程安装
  11. 你在公司项目里面看过哪些操蛋的代码?
  12. 免费视频文件生成视频二维码的方式详解
  13. PTA-查询水果价格
  14. 日常使用计算机如何进行病毒防范,电脑日常生活中怎么防范电脑病毒
  15. 心理压力测试脸型软件,脸型测试app
  16. 山东大学项目实训——地图圈系统——微信小程序(18)
  17. mac的计算机名称,mac 如何修改计算机名_mac 修改计算机名称
  18. 昨天学会2件事,一件是multisim 添加自定义模型或导入模型文件,包括opa695和9013等三极管
  19. 计算机内无法使用搜狗,技巧:IE11无法使用搜狗输入法的原因及解决方法
  20. 软件工程笔记:通用职责分配模式(grasp)

热门文章

  1. Linux内核中makefile有什么作用?深入解析makefile工作过程和原理
  2. int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
  3. raid 物理盘缓存状态_CDN与其他层面缓存
  4. python安装mysqldb模块_python MysqlDb模块安装及其使用详解
  5. Django模板:url反向解析
  6. Android工程Gradle仓库配置及说明
  7. element 动态加载下拉框_记一次很坑的需求:给element-cascader添加一个重置和确定按钮...
  8. ECS中的Entity实体
  9. 幼儿园小班上计算机课 作业内容是手口一致,小班幼儿手口不能一致的点数怎么办...
  10. OpenShift 4 之 配置基于Red Hat SSO的Identity Providers