前言:
react 框架自带的 state 在操作数据的时候,能够实现数据双向绑定,虽然好用,但是在组件传递的时候,尤其是多层组件传递数据,就变的不可预测,把自己给玩蒙了。redux 就是解决统一数据流,数据流完全可控并可追踪。要实现该目标,便需要进行相关的约束。Redux 由此引出了 dispatch action reducer 等概念,对state的概念进行强约束。然而对于一些项目来说,太过僵硬,便失去了灵活性。Mobx 便是来填补此空缺的。
这里对Redux和Mobx进行简单的对比:
Redux的编程范式是函数式的而Mobx是面向对象的;
因此数据上来说Redux理想的是immutable (不可变的)的,每次都返回一个新的数据,而Mobx从始至终都是一份引用。因此Redux是支持数据回溯的;
然而和Redux相比,使用Mobx的组件可以做到精确更新,这一点得益于 Mobx 的observable;对应的,Redux 是用 dispath 进行广播,通过 Provider 和 connect 来比对前后差别控制更新;Mobx更加精细一点。
一、安装
npm install --save-dev mobx mobx-react @babel/plugin-proposal-decorators
二、暴露一个变量
// 引入observable
import { observable } from "mobx";
// 监听 a 的状态
export default observable({
"a" : 0
});
observable: 通过 observable(state) 定义组件的状态,包装后的状态是一个可观察数据(Observable Data)。Observable 值可以是JS基本数据类型、引用类型。
三、变量照耀全局
main.js
import React from "react";
import ReactDom from "react-dom";
import App from "./App";
// 引入
import store from "./reducer/starReducer";
// 照耀
ReactDom.render(<App store = {store}/>,document.getElementById("app"));
四、装饰器装饰
observer: 通过 observer(ReactComponent) 定义组件
import React,{Component} from "react";
//引入 装饰器
import {observer} from 'mobx-react';
@observer
export default class App extends Component{
constructor(){
super();
}
render(){
return (
<div>
<h1>{this.props.store.a}</h1>
<button onClick = {()=>{this.props.store.a+=10}}>按我加一</button>
</div>
);
}
}
redux 和 Mobx 的最大区别就是?
Mobx 的优势来源于可变数据(Mutable Data)和可观察数据 (Observable Data) 。
Redux 的优势来源于不可变数据(Immutable data)。
Mobx 相比于redux 更加智能。
语法
export default class Store {
@observable price = 99;
@observable a = 199;
// constructor(price) {
// this.price = price;
// }
// @computed get total() {
// return this.price * this.a;
// }
}
使用这种语法,会在 CMD 里面报如下的错:
syntax 'classProperties' isn't currently enabled
说明环境支持在类里面初始化赋值。除了需要配置的环境是支持语法糖还需支持值可在类里面进行初始化。安装 插件@babel/plugin-proposal-class-properties
,并配置 webpac.config.js 。配置条件如下:
{
"plugins": [
["@babel/plugin-proposal-class-properties", { "loose": true }]
]
}
==============
import React,{Component} from "react";
//引入 装饰器
import {observer} from 'mobx-react';
@observer
export default class App extends Component{
constructor(){
super();
}
render(){
return (
<div>
<h1>{this.props.store.a}</h1>
<button onClick = {()=>{this.props.store.a+=10}}>按我加十</button>
</div>
);
}
}
====
import React from "react";
import ReactDom from "react-dom";
import App from "./App";
// 引入
// import {autorun } from 'mobx';
import store from "./reducer/starReducer";
console.log(store.a);
// 照耀上下文
ReactDom.render(<App store = {store}/>,document.getElementById("app"));
import {observable,action} from 'mobx';
class TestStore {
// 被观察者
@observable a;
constructor() {
this.a = 11;
}
}
const store = new TestStore()
export default store;