Mobx + React 案例

下载 MobX

mobx 就是我们下载的 mobx 就是mobx库本身

mobx-react 可以让react 和 mobx 进行完美的结合

npm install mobx mobx-react

MobX 工作流程

img

action:是一个函数、可以更改store中的状态

state: store中的状态,状态发生改变自动同步到视图中

views:视图、视图想要更改状态则需要触发一个action来更改状态

MobX中实现计数器案例

初始化项目,并安装mobx相关依赖(参照开发前的准备)

create-react-app mobx-demo
cd mobx-demo
# 安装modx相关依赖及其相关设置初始化项目(这一步省略之前有讲)
npm start 

新建stores文件夹创建计数器案例的store

在项目中新建stores文件夹,创建counter.store.js文件,在这个文件中要创建store对象,默认存储状态0,在modxstore是由类创建的,所以我们需要用class去创建

class counterStore {
    count = 0
}
const counter = new counterStore()

export default counter

store放在一个全局的组件可以访问的地方,就是在根组件外用Provider包裹一层,把计数器store传入

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

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

在组件中访问计数器store,在组件中获取store对象需要使用到inject装饰器,通过这个装饰器这个类,通过这个装饰器去注入storeinject的参数就是把store的某个值注入给组件,会注入到组件的props

import React, { Component }  from 'react';
import { inject } from 'mobx-react'

// 把 counter注入到 组件的props里面
@inject('counter')
class App extends Component {
  render(){
    const { counter } = this.props
    return (<div>
      <span>{counter.count}</span>
    </div>)
  }
}

export default App;

这个时候组件就可以访问store

添加加减按钮实现计数器

创建加减方法来更改状态

class counterStore {
    count = 0
    // 更改状态的方法需要创建子在这个类中
    increment = () => {
        this.count = this.count + 1
    }
    decrement = () => {
        this.count = this.count - 1
    }
}

因为inject装饰器把counter注入到了组件所以可以通过counter来拿到方法绑定给按钮

@inject('counter')
class App extends Component {
  render(){
    const { counter } = this.props
    return (<div>
      <button onClick={counter.increment}>+</button>
      <span>{counter.count}</span>
      <button onClick={counter.decrement}>-</button>
    </div>)
  }
}

这个时候点击按钮发现视图并没有被改变,因为我们还需要把状态变为可观测状态,还需要把组件变成观察者这样才可以视图更新

// 1. 创建 store 对象 存储默认状态0
// 2. 将store对象放在一个全局的组件可以够得到的地方
// 3. 让组件获取store对象中的状态,并将状态显示在组件中
import { observable, makeObservable, action } from 'mobx'
class counterStore {
    // 通过 observable 装饰器把状态变成可观测状态
    @observable count = 0;
    constructor() {
        makeObservable(this)
    }

    // 更改状态的方法需要创建子在这个类中
    @action increment = () => {
        this.count = this.count + 1
    }
    @action decrement = () => {
        this.count = this.count - 1
    }
}
const counter = new counterStore()

export default counter

视图变为观察者

import React, { Component }  from 'react';
import { inject, observer, } from 'mobx-react'


// 把 counter注入到 组件的props里面
// observe 不需要传入参数
@inject('counter')
@observer
class App extends Component {
  render(){
    const { counter } = this.props
    return <div>
      <button onClick={counter.increment}>+</button>
      <span>{counter.count}</span>
      <button onClick={counter.decrement}>-</button>
    </div>
  }
}

export default App;

这样计数器案例就完成了

更正类中的普通函数的this指向

我们大多数情况创建action更改方法的时候都适用的普通函数,将才我们使用的箭头函数,改为普通函数发现this指向为undefined,这个时候怎么解决这个问题呢,其实很简单只需要在@action后面加上.bound就好了

@action.bound increment = function() {
  this.count = this.count + 1
}

@action.bound decrement = function() {
  this.count = this.count - 1
}