前言
先来看看Mobx官方对其描述:MobX 是一个身经百战的库,它通过运用透明的函数式响应编程(Transparent Functional Reactive Programming,TFRP)使状态管理变得简单和可扩展。
Mobx与Redux都是非常优秀的React状态管理方案,对于这两个状态管理方案的优点与不同,在此不做详细对比,此文主要基于Mobx6集成React和Typescript在项目中具体的使用方式进行说明。
Mobx6相比于Mobx5和Mobx4在具体的使用方式上都有很大的不同,在 MobX 6 中不推荐使用装饰器语法,因为它不是 ES 标准,并且标准化过程要花费很长时间,但是通过配置仍然可以启用装饰器语法。
初始化React工程
本案例采用create-react-app来快速创建react与typescript的环境。需要安装依赖如下:
- mobx
- mobx-react或者mobx-react-lite
- 创建store目录
src目录下新建mobxStore文件夹,并依次创建index.ts,timer.ts,user.ts文件。
// timer.ts
import { makeAutoObservable } from 'mobx';
// 定义timer数据领域接口
export interface TimerStoreType {
timer: number;
addTimer: Function;
resetTimer: Function;
}
class TimerStore implements TimerStoreType {
timer = 0;
constructor() {
// mobx6的不同,函数式,而不再通过使用装饰器
makeAutoObservable(this);
}
addTimer() {
this.timer += 1;
}
resetTimer() {
this.timer = 0;
}
}
export { TimerStore };
// user.ts
import { makeObservable, observable, computed, action } from 'mobx';
// 定义user数据领域store接口
export interface UserStoreType {
name: string;
age: number;
doubleAge: number;
editName: (str: string) => void;
}
class UserStore {
name = '张三';
age = 18;
get doubleAge() {
return this.age * 2;
}
constructor() {
// makeObservable需要手动注解
makeObservable(this, {
name: observable,
age: observable,
doubleAge: computed,
editName: action,
});
}
editName(str: string) {
this.name = str;
}
}
export { UserStore };
// index.ts
import { createContext } from 'react';
import { TimerStore, TimerStoreType } from './timer';
import { UserStore, UserStoreType } from './user';
// 单一Store类型,class组件props需要
export type { TimerStoreType, UserStoreType };
// root store mobx-react Provider 使用
export const stores = {
timerStore: new TimerStore(),
usertore: new UserStore(),
};
// root store fn组件 useContext使用
export const useStore = createContext(stores);
- react根应用基于context模式提供store
// 入口文件 index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import AppMobx from './AppMobx';
import { Provider } from 'mobx-react';
import { stores } from './mobxStore/index';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<Provider {...stores}>
<AppMobx></AppMobx>
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
// AppMobx.tsx
import React from 'react';
// class 组件使用demo
import ClassPage from './pages/MobxDemo/ClassPage';
// function组件使用demo
import FnPage from './pages/MobxDemo/FnPage';
function AppMobx() {
return (
<div>
<h3>mobx class组件用法</h3>
<ClassPage></ClassPage>
<hr />
<h3>mobx function组件用法</h3>
<FnPage></FnPage>
</div>
);
}
export default AppMobx;
- 组件中使用sotre数据
class组件使用demo,其中,class组件的使用又可以分为函数式用法和装饰器用法,首先来看类组件中的装饰器用法,注意,如需使用装饰器,需要进行启用配置
import React from 'react';
import { observer, inject } from 'mobx-react';
import { TimerStoreType } from '../../mobxStore/index';
// props需要声明
interface IProps {
// timer数据域
timerStore?: TimerStoreType;
}
interface IState {}
@inject('timerStore')
@observer
class ClassPage extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props);
this.addMobx = this.addMobx.bind(this);
this.resetMobx = this.resetMobx.bind(this);
this.state = {};
}
addMobx() {
this.props.timerStore?.addTimer();
}
resetMobx() {
this.props.timerStore?.resetTimer();
}
render() {
const { timerStore } = this.props;
return (
<div>
<p>当前timer值:{timerStore?.timer}</p>
<button onClick={this.addMobx}>mobx值+1</button>
<button onClick={this.resetMobx}>重置</button>
</div>
);
}
}
export default ClassPage;
class组件的函数式用法如下:
import React from 'react';
import { observer, inject } from 'mobx-react';
import { TimerStoreType } from '../../mobxStore/index';
interface IProps {
timerStore?: TimerStoreType;
}
interface IState {}
class ClassPage extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props);
this.addMobx = this.addMobx.bind(this);
this.resetMobx = this.resetMobx.bind(this);
this.state = {};
}
addMobx() {
this.props.timerStore?.addTimer();
}
resetMobx() {
this.props.timerStore?.resetTimer();
}
render() {
const { timerStore } = this.props;
return (
<div>
<p>当前timer值:{timerStore?.timer}</p>
<button onClick={this.addMobx}>mobx值+1</button>
<button onClick={this.resetMobx}>重置</button>
</div>
);
}
}
// 重点在这里
// inject注入timerStore
export default inject('timerStore')(observer(ClassPage));
function组件使用参考如下:
import React, { useContext } from 'react';
import { observer } from 'mobx-react';
// 单独引入需要数据域store
import { useStore } from '../../mobxStore/index';
interface IProps {}
const FnPage: React.FC = (props: IProps) => {
// hook useContext
const { timerStore } = useContext(useStore);
return (
<div>
<p>当前timer值:{timerStore.timer}</p>
<button onClick={() => timerStore.addTimer()}>mobx值+1</button>
<button onClick={() => timerStore.resetTimer()}>重制</button>
</div>
);
};
export default observer(FnPage);
总结
此文只是仅仅介绍了Mobx6集成React和Typescript的使用案例说明,供有需要了解的同学们参考。下篇文章会对mobx和mobx-react两个模块的核心api进行源码的分析,只要了解了源码的实现,我们才能在具体的项目中更好的使用mobx来进行状态管理。