前言

目前React框架越来越火,使用 react 公司越来越多!随着页面逻辑的复杂度提升,各种状态库也层次不穷,业内比较成熟的解决方案有 Redux、但是Redux使用相对繁琐,对于新手来说不友好。所以今天特意推荐大家可以去尝试使用另一个比较成熟的状态管理工具Mobx,mobx 的核心理念是 简单、可扩展的状态管理库。

个人感觉它和vuex有很多相似之处,如果你会vuex十分钟就可以搞定。

Mobx它通过透明的函数响应式编程(transparently applying functional reactive programming - TFRP)使得状态管理变得简单和可扩展。

准备工作

可以使用create-react-app构建一个react项目,也可以看我之前写的webapck小白成神之路文章手动搭建一套react项目(个人推荐第二种,手动搭建会学到很多知识点)

环境配置

安装mobx mobx-react

  npm install --save mobx mobx-react

因为要用到装饰器,所以需要安装一个依赖去解析

  npm i --save-dev babel-plugin-transform-decorators-legacy

然后在.babelrc配置

{"presets": ["react", "env", "stage-0"], "plugins": ["transform-runtime", "transform-decorators-legacy"]
}

observable

仓库

新建test.js

import {observable} from 'mobx';class TestStore {// 被观察者@observable name; constructor() {this.name = '浮云先生'}
}
const test = new TestStore()
export default test

可以看到我们在数据仓库中写入name = "浮云先生",

observer

组件

import React from 'react'
import ReactDOM from 'react-dom'
import {observer, inject} from 'mobx-react';// 观察者
@inject('test')
@observer
class DemoComponent extends React.Component {constructor(props) {super(props);}render() {const { test } = this.props;return (<div><p>{test.name}</p></div>);}
}export default DemoComponent;
  • inject 在模块内用 @inject('Store'),将 Store 注入到 props 上,保证结构的一致性
    使用 @observer ,将组件变为观察者,响应 name 状态变化。
    当状态变化时,组件也会做相应的更新。

computed

有时候,state 并不一定是我们需要的最终数据。例如,所有的 todo 都放在 store.todos 中,而已经完成的 todos 的值(store.unfinishedTodos),可以由 store.todos 衍生而来。

对此,mobx 提供了 computed 装饰器,用于获取由基础 state 衍生出来的值。如果基础值没有变,获取衍生值时就会走缓存,这样就不会引起虚拟 DOM 的重新渲染。

通过 @computed + getter 函数来定义衍生值(computed values)。

import { computed } from 'mobx';class Store {@observable todos = [{title: "todo标题",done: false,},{title: "已经完成 todo 的标题",done: true,}];@computed get finishedTodos () {return  this.todos.filter((todo) => todo.done)}
}

这样组建中就可以直接拿到finishedTodos 过滤后的值了

action

首先在 Store 中,定义action(动作)(test.js)

import {observable, action} from 'mobx';class TestStore {@observable name; // 定义action(动作)@action changeName = name => {this.name = name}constructor() {this.name = '浮云先生'}
}
const test = new TestStore()
export default test

在组件中只需要this.props.test.changeName ('改变')调用就可以。是不是很简单~

异步请求

方式1:runInAction/async/await

import {observable, action} from 'mobx';
class MyState {@observable data = null;@observable state = null;@action initData = async () => {try {const data = await getData("xxx");runInAction("说明一下这个action是干什么的。不写也可以", () => {this.state = "success"this.data = data;})} catch (error) {runInAction(() => {this.state = "error"})}};
}

方式2:flows

更好的方式是使用 flow 的内置概念。它们使用生成器。一开始可能看起来很不适应,但它的工作原理与 async / await 是一样的。只是使用 function * 来代替 async,使用 yield 代替 await 。 使用 flow 的优点是它在语法上基本与 async / await 是相同的 (只是关键字不同),并且不需要手动用 @action 来包装异步代码,这样代码更简洁。

class Store {@observable data = null;@observable state = null;fetchProjects = flow(function * () { // <- 注意*号,这是生成器函数!try {const projects = yield getData() // 用 yield 代替 await// 异步代码块会被自动包装成动作并修改状态this.state = "success"this.data = projects} catch (error) {this.state = "error"}})
}

大型项目中定义多个状态(模块化)

假如我们有两个模块分别是test.js和mast.js
test.js

import {observable, action} from 'mobx';class TestStore {@observable name; @observable age;@action changeAge = i => {this.age = this.age + Number(i)}constructor() {this.name = '浮云先生'this.age = 25}
}
const test = new TestStore()
export default test

mast.js

// 这里引入的是 mobx
import {observable, computed, action} from 'mobx';class MastSotre {@observable list; @computedget getList () {return this.list.filter(v => v.id !== 1)}@actionaddList = obj => this.list.push(obj)constructor() {this.list = [{name: '香蕉',id: 0},{name: '苹果',id: 1},{name: '西瓜',id: 2}]}
}
const mast = new MastSotre()
export default mast

新建index.js进行汇总

// 汇总store
import test from './test'
import mast from './mast'const stores = {test,mast,
}
export default stores

在入口文件中全局注入数据

import React from 'react'
import ReactDOM from 'react-dom'
import RouterContainer from './router/index'
import { Provider } from "mobx-react"
import stores from './store'import {configure} from 'mobx'; // 开启严格模式
configure({enforceActions: true}) // 开启严格模式ReactDOM.render(<Provider {...stores}><RouterContainer/></Provider>,document.getElementById('example')
);
  • Provider 通过 Provider 渗透
  • configure 代表开启了严格模式,因为非严格模式下,组件是直接可以通过props.action改变state数据的,当项目复杂的时候这样是非常危险的。所以要设置唯一改变state方式是通过action

简单的对常用的知识点进行了汇总,同学们看了后是不是觉得很简单!
想要深入学习的Mobx官网传送门:https://cn.mobx.js.org/

作者:抱紧我_8204
链接:https://www.jianshu.com/p/6a12b3121379
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

React之mobx、mobx-react 入门相关推荐

  1. 翻译君Mobx,Ten minute introduction to MobX and React

    简要介绍:最近看了一下Mobx,然后有一篇入门教程是英文的,这里翻译一下并写写自己的心得体会. 原文地址:https://mobx.js.org/getting-started.html 一.Mobx ...

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

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

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

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

  4. react dispatch_梳理下redux、mobx 在react的应用

    ❝ 本文整理下近期 redux.mobx 在 react 中的使用对比,大家可以根据个人喜好,合理使用 查看完整 demo ❞ redux 状态管理 redux 基本使用流程 ❝ 首先把 redux ...

  5. 从零配置webpack(react+less+typescript+mobx)

    本文目标 从零搭建出一套支持react+less+typescript+mobx的webpack配置 最简化webpack配置 首页要初始化yarn和安装webpack的依赖 yarn init -y ...

  6. mobx在react如何使用

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

  7. 【MobX】390- MobX 入门教程(上)

    点击上方"前端自习课"关注,学习起来~ 本文考虑到篇幅问题,将<MobX 入门教程>分成上.下两篇文章,方便阅读.分配安排: 一.MobX 介绍 首先看下官网介绍: ★ ...

  8. native react 常用指令_React Native入门基础篇(一)

    学习一次,随处书写.(以下文字来自各大网上资料整理而来,侵删!) 概述 使用React为Android和iOS创建本机应用 React Native将本机开发的最佳部分与React(用于构建用户界面的 ...

  9. React学习笔记一(React入门+JSX+脚手架)

    文章目录 1. React介绍和特点 1.1 React是什么 1.2 React的特点 2. React的开发依赖 2.1 React的三个依赖 2.2 Babel和React的关系 2.3 Rea ...

  10. react ssr 服务端渲染入门

    react ssr 服务端渲染入门 前言 前后端同构,作为针对单页应用 SEO 优化乏力.首屏速度瓶颈等问题而产出的解决方案,近来在 react.vue 等前端技术栈中都得到了支持.当我们正打算抛弃传 ...

最新文章

  1. WEB服务器和HTTP服务器和应用服务器的区别?(web服务器就是HTTP服务器)为什么要把Web服务器独立配置,和应用程序服务器一前一后?
  2. postman返回值设置为全局变量
  3. [蓝桥杯][算法提高VIP]盾神与积木游戏(贪心)
  4. 【mysql必知必会】第十二章 汇总数据
  5. 2017年3月计算机二级c语言真题,2017年3月计算机二级C语言习题及答案
  6. 使用Rotativa在ASP.NET Core MVC中创建PDF
  7. python的简洁运算符_Python实现的简单算术游戏实例 python中算数运算符都有哪些...
  8. 狂神说SpringCloud学习笔记
  9. Three.js - 光源使用详解3(环境光 HemisphereLight、镜头光晕 LensFlare)
  10. mac写python用什么软件_Mac安装软件,一条指令就搞定
  11. No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-androideabi
  12. Ranking 排行
  13. 在我的新书里,尝试着用股票案例讲述Python爬虫大数据可视化等知识
  14. COLA之架构演变(一)
  15. 中科大计算机网络空间安全,2020年中国科学技术大学网络空间安全考研经验分享...
  16. Android 设置APP启动图标
  17. 图解Semaphore信号量之AQS共享锁-非公平模式
  18. oracle时间相减
  19. 家长育儿风格决定教育效果!
  20. Linux信号量 sem_t简介

热门文章

  1. 山东农村商业银行高校毕业生招聘
  2. Python爬虫+selenium——爬取淘宝商品信息和数据分析
  3. 达梦数据库之DM8_实时数据守护配置
  4. day02 智能合约
  5. 【恒指早盘分析】盘点技术分析的三个误区
  6. [Linux]Ubuntu中的System Setting
  7. CEF Extensions
  8. Unity3D人物换装
  9. 探索人机未来:人机融合智能
  10. 选择数字IC行业,就一定要读研吗?