react和mox结合

observable 的属性值在其变化的时候 mobx 会自动追踪并作出响应。

数据流

在一个数据管理框架库中,其最重要的就是它的数据管理模式了,也就是其数据流。对于 MobX 来说,它的数据流简明清晰,并且也是单向数据流

它由几个部分组成:Actions、State、Computed Values、Reactionsa

在整个数据流中,通过事件驱动(UI 事件、网络请求…)触发 Actions,在 Actions 中修改了 State 中的值,这里的 State 既应用中的 store 树(存储数据),然后根据新的 State 中的数据计算出所需要的计算属性(computed
values)值,最后响应(react)到 UI 视图层。

客观察状态(State)

@observable 修饰器转可观测一个数据,@observable 接受任何类型的 js 值(原始类型、引用、纯对象、类实例、数组和、maps),如果变化的值处在autorun中,那么autorun就会自动执行。

@observable  classProperty = value

当应用状态更新时,所有依赖于这些应用状态的监听者(包括UI、服务端数据同步函数等),都应该自动得到细粒度地更新。

当然在这里可以加一些调节器来做一些配置:

  • @observable.deep (默认)对对象进行深拷贝;
  • @observable.shallow 它只对对象进行浅拷贝;
  • @observable.ref 禁用对象的自动转化,只转化其引用; 安装依赖项: mobx, mobx-react

计算属性 computed

const number = observable(10);
const plus = computed(() => number.get() > 0);

autorun(() => {
     
  console.log(plus.get());
});

number.set(-19);
number.set(-1);
number.set(1);

依次输出了true,false,true。
第一个true是number初始化值的时候,10>0为true没有问题。
第二个false将number改变为-19,输出false,也没有问题。
但是当-19改变为-1的时候,虽然number变了,但是number的改变实际上并没有改变plus的值,所以没有其它地方收到通知,因此也就并没有输出任何值。
直到number重新变为1时才输出true。
顺便一提,computed属性和React Native中的ListView搭配使用很愉快。

action,runInAction和严格模式(useStrict)

修改被观测变量的行为放在action中。

import {
     observable, action} from 'mobx';
class Store {
     
  @observable number = 0;
  @action add = () => {
     
    this.number++;
  }
}

const newStore = new Store();
newStore.add();

Mobx的非严格模式

import {
     observable, action, useStrict} from 'mobx';
useStrict(true);

如果你使用async function来处理业务,那么我们可以使用runInAction这个API来解决之前的问题

import {
     observable, action, useStrict, runInAction} from 'mobx';
useStrict(true);

class Store {
     
  @observable name = '';
  @action load = async () => {
     
    const data = await getData();
    runInAction(() => {
     
      this.name = data.name;
    });
  }
}

在react中使用mobx

安装

npm i mobx mobx-react

## 装饰器语法babel7

 cnpm install --save-dev @babel/plugin-proposal-decorators

.babelrc文件配置

{
     
  "presets": [
    "react-app"
  ],
  "plugins": [
    [
      "@babel/plugin-proposal-decorators",
      {
     
        "legacy": true
      }
    ],
  ]
}

react中的入口文件index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {
      Provider } from 'mobx-react'
import Store from './store/index'
ReactDOM.render(<Provider {
     ...Store}><App /></Provider>, document.getElementById('root'));
//Provider为根
//如果使用Provider配合inject,把多个store,配到根上,子组件通过inject自动注入。

react中的页面文件 App.js

import React, {
      Component } from 'react'
import {
      inject, observer } from 'mobx-react'
//注入文件
@inject('homeStore')
@observer
class ComponentName extends Component {
     
  render() {
     
    return (
      <div>
        <h3>{
     this.props.homeStore.num}</h3>
        <button onClick={
     () => {
      this.props.homeStore.add() }}>加一</button>
      </div>
    )
  }
  componentDidMount() {
     
  //调用日志
    console.log(this.props.homeStore.total)
  }
}
export default ComponentName;

store文件下index.js

import Homestore from './home/index'
const homeStore = new Homestore()
export default{
     
    homeStore
}

store文件下hoem/index.js

import {
      observable, action, autorun, computed } from 'mobx'
class Homestore {
     
    //初始化状态
    @observable num = 0
    //
    constructor() {
     
        this.num = 0;
    }
    //计算属性
    @computed get total() {
     
        return this.num
    }
    set tol(value) {
     
        this.num = 10
    }
    //触发行为
    @action add() {
     
        this.num += 1;
    }
}
//可以看成日志,状态变化,日志就会触发
autorun(() => {
     
    console.log(Homestore.prototype.num);
});
export default Homestore;

你可能感兴趣的:(react)