下面先介绍一些启用装饰器用法的先关内容
TypeScript
在 tsconfig.json
中启用编译器选项 "experimentalDecorators": true
。
Babel: 使用 babel-preset-mobx
另外一种在 Babel 中配置 MobX 的方式是使用 mobx
preset,这种方式更方便,其中包含了装饰器及其他几个经常与 mobx 一起使用的插件:
npm install --save-dev babel-preset-mobx
.babelrc:
{
"presets": ["mobx"]
}
Babel: 手动启用装饰器
要启用装饰器的支持而不使用 mobx preset 的话,需要按照下列步骤。 安装支持装饰器所需依赖: npm i --save-dev babel-plugin-transform-decorators-legacy
。 并在 .babelrc
文件中启用:
{
"presets": ["es2015", "stage-1"],
"plugins": ["transform-decorators-legacy"]
}
注意,插件的顺序很重要: transform-decorators-legacy
应该放在首位。 babel 设置有问题?请先参考这个 issue 。
主要包含的包
- mobx-react 提供 mobx 到 react 之间的链接。
- mobx-react-devtools 提供了开发者工具的支持。
import {observer} from 'mobx-react'
import DevTool from 'mobx-react-devtools'
@observer
class App extrnds React.Component{
constructor(props){
super(props);
this.state = {};
}
render(){
return(
<div className='app_content'>
<DevTools />
{tihs.props.children}
</div>
);
}
}
- mobx-react 提供了 Provider 来包裹应用,以传递 store
- mobx-react 提供了 inject 用来将对应 store 注入到组件中
import {observer, inject, Provider, observable} from 'mobx-react'
class Store {
@observable name = 'xiaobai'
}
const stroes = {
initStore: new Store()
}
@inject('initStore') // 字符串是要挂载在组件上的 store,可在 this.props.initStore 上访问到
@observer // 这个装饰器必须在最深层
class APP extends React.Component{
render(){
return <div>App</div>
}
}
ReactDOM.render((
<Provider {...stores}>
<App />
</Provider>
), document.getElementById('container'));
- configure 由 mobx 提供,只要用于配置 mobx。
import {configure} from 'mobx'
// 状态始终需要通过动作来更新(实际上还包括创建)
configure({enforceActions: 'always'});
- 生命周期钩子
import {observer} from 'mobx-react'
@observer
class App extends React.Component{
componentWillReact(){
// 将在每次 状态更新后执行,但是是在 render 之前执行的
}
}
需要注意的是
componentWillReact 不接收参数;
componentWillReact 初始化渲染前不会触发 (使用 componentWillMount 替代);
componentWillReact 对于 mobx-react@4+, 当接收新的 props 时并在 setState 调用后会触发此钩子;
setState 的替代方案
可以使用 observable 观察组件属性来更新 UI,从而代替 setState。这种替换方法不是推荐方法。
只要使用 observer 包装的组件。
- 可以使用 action 包装类方法作为动作。
- 使用 observable 包装的属性可以作为观察属性。
- computed 进行计算属性的定义
import React, {Component} from 'react';
import {inject, observer} from 'mobx-react';
import {observable, action} from "mobx";
import './style.css';
@inject('commonStore')
@observer
export default class Timer extends Component{
constructor(props){
super(props);
this.state = {};
}
@observable secondsPassed = 0;
componentWillMount(){
this.props.commonStore.startTime();
this.timer = setInterval(this.handleChangeSecondsPassed,1000);
}
@action.bound handleChangeSecondsPassed(){
this.secondsPassed ++;
}
render(){
const {time} = this.props.commonStore;
return(
<div className='time_content'>
<div>{time}</div>
<div>Seconds passed:{this.secondsPassed}</div>
</div>
);
}
}