简单使用mobx

328 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

1、配置mobx

创建项目后 先使用 npm run eject 弹出webpack配置 然后直接敲y 搞定

安装mobx

npm i mobx 

如果git冲突(没有则请无视)

git add .

回车

git commit -m ''

回车

// ​ 注意不要git push

安装mobx-react

npm i mobx-react

安装支持装饰器所需依赖

npm i babel-plugin-transform-decorators-legacy -D @babel/preset-env -D babel-plugin-transform-class-properties -D @babel/plugin-proposal-decorators -D

配置package.json

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

2、使用mobx

现在建一个store/user.js存储数据 其中可以使用@observalbe 和 @action来声明数据和方法

import { observable, action, computed } from 'mobx'

class user {
  userInfo = 0
  @observable num2 = 1
  @observable num3 = 1

  @computed
  get count() {
    return this.num2 + this.num3
  }
  
  @action getUSerInfo() {
    // 异步请求 res
    this.userInfo = {
      id: 1,
      name: '222'
    }
  }
}

export default new user()

现在建一个store/index.js导出数据

import user from './user'

const store = {
  user
}

export default store

在入口文件文件,src/index.js中使用Provider

import ReactDOM from 'react-dom';
import App from './App';
import store from './store'
import {Provider} from 'mobx-react'

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

哪个组件使用 , 就在哪个组件中 “注入” inject

import { Component } from 'react'
import {inject,observer} from 'mobx-react'
@inject('user')
@observer
export default class CountNum extends Component
{
    userInfo(){
        this.props.user.getUSerInfo();
    }
    render()
    {
        return (
            <div>
                <h2>计数器</h2>
                {this.props.user.num2}
                {this.props.user.num3}
                <button onClick={this.userInfo}>+</button>
            </div>
        )
    }
}

注意 要在类的上方使用修饰器 @observer 声明这个组件是一个被监听的组件  否则 数据不能随之改变 

Mobx的一些坑

通过autorun的实现原理可以发现,会出现很多我们想象中应该触发,但是没有触发的场景,例如:

  1. 无法收集新增的属性
 
const Mobx = require("mobx");
const { observable, autorun } = Mobx;
let ob = observable({ a: 1, b: 1 });
autorun(() => {
  if(ob.c){
    console.log("ob.c:", ob.c);
  }
});
ob.c = 1

对于该问题,可以通过

extendObservable(target, props)

方法来实现。

 
const Mobx = require("mobx");
const { observable, autorun, computed, extendObservable } = Mobx;
var numbers = observable({ a: 1, b: 2 });
extendObservable(numbers, { c: 1 });
autorun(() => console.log(numbers.c));
numbers.c = 3;
 
// 1
 
// 3

extendObservable该API会可以为对象新增加observal属性。

当然,如果你对变量的entry增删非常关心,应该使用Map数据结构而不是Object。

  1. 回调函数若依赖外部环境,则无法进行收集
 
const Mobx = require("mobx");
const { observable, autorun } = Mobx;
let ob = observable({ a: 1, b: 1 });
let x = 0;
autorun(() => {
  if(x == 1){
    console.log("ob.c:", ob.b);
  }
});
x = 1;
ob.b = 2;

很好理解,autorun的回调函数在预执行的时候无法到达ob.b那一行代码,所以收集不到。