1.mobx简介
mobx简单,可扩展的状态管理库。
react和mobx是一对强有力组合,react负责渲染应用的状态,mobx负责管理应用状态供react使用。
mobx5版本要求浏览器支持es6 proxy,不支持ie11,nodejs6
mobx4可以运行在任何支持es5的浏览器上
mobx4和5的api是相同的
2.开发前的准备
2.1 启用装饰器语法支持(方式一)
1.弹射项目底层配置:npm run eject
2.下载装饰器语法babel插件:npm install @babel/plugin-proposal-decorators
3.在package.json文件中加入配置
package.json
"babel": {
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
]
]
}
2.2 启用装饰器语法支持(方式二)
- npm install react-app-rewired @babel/plugin-proposal-decorators customize-cra
- 在项目根目录下创建 config-overrides.js
config-overrides.js
const {
override, addDecoratorsLegacy } = require("customize-cra");
module.exports = override(addDecoratorsLegacy());
-
package.json
"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", }
解决vscode编辑器关于装饰器语法的警告
“javascript.implicitProjectConfig.experimentalDecorators”: true
3.mobx+react
npm install mobx mobx-react --save
mobx工作流程:
工作流程流程描述:
视图想要更改:通过触发action,action的触发导致状态得到变更,当状态发生变更,再把这个状态同步给视图。
案例:计数器
注意版本:
"mobx": "^5.15.4",
"mobx-react": "^6.2.2",
- 创建store对象,存储默认状态
store/CounterStore.js
// 1。创建store对象,存储默认状态
// 2.将store对象放在一个全局的组件可以得到的地方。 Provider
// 3.让组件获取store对象中的状态,并将状态显示在组件中
import {
observable, action } from "mobx"
class CounterStore {
// @observable使数据变成可观测的数据
@observable count = 0
// 注意这里是箭头函数,如果是普通函数写法如下:()
// increment = () => {
// this.count = this.count + 1
// }
// .bound更正类中的普通函数的this指向。普通函数中this是undefined
@action.bound increment (){
this.count = this.count + 1
}
decrement = () => {
this.count = this.count - 1
}
}
const counter = new CounterStore()
export default counter
2.将store对象放在一个全局的组件可以得到的地方。 Provider
provider
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {
Provider } from 'mobx-react'
import counter from './stores/CounterStore'
ReactDOM.render(
<Provider counter={
counter}>
<React.StrictMode>
<App />
</React.StrictMode>
</Provider>,
document.getElementById('root')
);
3.让组件获取store对象中的状态,并将状态显示在组件中
App.js
import React, {
Component } from 'react'
import {
inject, observer } from 'mobx-react'
// 通过inject装饰器将counter注入到组件中
// @observer使组件变成观察者
@inject('counter')
@observer
class App extends Component {
render() {
// 可以获取到counter
console.log(this.props.counter)
const {
counter } = this.props
return (
<div>
<button onClick={
counter.increment}>+</button>
<span>{
counter.count}</span>
<button onClick={
counter.decrement}>-</button>
</div>
);
}
}
export default App
4.mobx异步
store/CounterStore.js
// 1。创建store对象,存储默认状态
// 2.将store对象放在一个全局的组件可以得到的地方。 Provider
// 3.让组件获取store对象中的状态,并将状态显示在组件中
import {
observable, action, runInAction } from "mobx"
import axios from 'axios'
class CounterStore {
// 可观测的数据
@observable count = 0
@observable users = []
// increment = () => {
// this.count = this.count + 1
// console.log(this.count)
// }
// decrement = () => {
// this.count = this.count - 1
// }
// 箭头头函数改成普通函数
@action.bound increment() {
this.count = this.count + 1
}
// 如果有异步操作,不能直接在这个函数中操作数据。处理方法如下:
// 方法1.runInAction
// @action.bound async getData () {
// let { data } = await axios.get('https://api.github.com/users');
// runInAction(() => {
// this.users = data || [{id: '1', login: '1'}]
// })
// }
// 方法2:flow
getData = flow(function * (){
let {
data } = yield axios.get('https://api.github.com/users');
this.users = data || [{
id: '1', login: '1'}]
}).bind(this)
}
const counter = new CounterStore()
export default counter
5.mobx数据检测
数据检测:当某一个状态发生变化的时候我们想根据这个值得到另外一个值
计算值:可以根据现有的状态或其他计算值衍生出的值
mobx提供的方法:
1.computed
什么时候使用计算值?
将复杂的业务逻辑从模板中进行抽离。
式例:
import {
observable, action,computed} from 'mobx'
class BirdStore{
@observable count = 10
@observable price = 25
+ // 调用的时候可以不加括号,以属性的形式使用它。
@computed get totalPrice() {
return this.count * this.price
}
}
- 禁止普通函数更改程序状态并引入action装饰器。
默认情况下所有的函数都可以更改程序的状态,但是我们觉得这样是不好的,如果程序状态出现了问题,我们不得不排查每一个更改应用程序状态的函数,这样开发成本就比较高的,所以我们要把这个默认行为禁止掉,也就是不希望所有的函数都可以更改应用程序的状态。我们强制规定只有@action函数可以更改应用程序的状态,降低了程序的开发成本。
// 1。创建store对象,存储默认状态
// 2.将store对象放在一个全局的组件可以得到的地方。 Provider
// 3.让组件获取store对象中的状态,并将状态显示在组件中
import {
observable, action, runInAction, flow, configure } from "mobx"
import axios from 'axios'
// 通过配置强制程序使用action函数更改应用程序中的状态
configure({
enforceActions: 'observed'})
class CounterStore {
// 可观测的数据
@observable count = 0
@observable users = []
+ @action increment = () => {
this.count = this.count + 1
console.log(this.count)
}