持续创作,加速成长!这是我参与「掘金日新计划 · 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的实现原理可以发现,会出现很多我们想象中应该触发,但是没有触发的场景,例如:
- 无法收集新增的属性
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。
- 回调函数若依赖外部环境,则无法进行收集
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那一行代码,所以收集不到。