前言
之前项目中状态管理清一色的都是用redux,各种redux实践也尝试过,但是给人感觉还是特别的重(redux-toolkit还不错),因此入坑尝试口碑不错的mobx
Begin
创建一个Store
这里我们以一个todolist为例子
import { observable, action, makeObservable } from 'mobx';
class Todo {
constructor() {
// mobx6.0后的版本都需要手动调用makeObservable(this),不然会发现数据变了视图不更新
makeObservable(this);
}
@observable list = [
{
label: 'exec',
finish: false,
},
{
label: 'study',
finish: false,
},
];
@action
finsh(label: string) {
let list = [...this.list];
list.map(item => {
if (item.label === label) {
item.finish = true;
}
return item;
});
this.list = list;
}
}
const todoStore = new Todo();
export default todoStore;
复制代码
@observable
创建一个可响应的变量,注意这里并不是原始变量
@action
这其实就是redux
中的action
,据说老版本中mobx是直接修改state的,听起来就非常不安全。这种使用action触发动作的形式似乎更能让人接受
编写业务组件
获取响应式数据,我们一般有两种形式,一种是直接引入定义的Store, 一种是利用Provider和inject来注入到组件的props中
直接引入store
import React from 'react';
import { observer } from 'mobx-react';
import todoStore from '../../store/todo'
@observer
class Todo extends React.Component{
render() {
return (
<div className="todolist">
<div className="unfinish">
{todoStore.list.map(item => (
<div key={item.label} style={{ display: 'flex' }}>
{!item.finish && (
<>
<span>{item.label}</span>
<button onClick={() => todoStore.finsh(item.label)}>do</button>
</>
)}
</div>
))}
</div>
<div className="finish">
{todoStore.list.map(item => (
<div key={item.label}>{item.finish && <span>{item.label}</span>}</div>
))}
</div>
</div>
);
}
}
export default Todo;
复制代码
父组件
<div>
<Todo />
</div>
复制代码
使用Provider和inject
import React from 'react';
import { observer, inject } from 'mobx-react';
@inject('todoStore')
@observer
class Todo extends React.Component{
render() {
const { todoStore } = this.props
return (
<div className="todolist">
<div className="unfinish">
{todoStore.list.map(item => (
<div key={item.label} style={{ display: 'flex' }}>
{!item.finish && (
<>
<span>{item.label}</span>
<button onClick={() => todoStore.finsh(item.label)}>do</button>
</>
)}
</div>
))}
</div>
<div className="finish">
{todoStore.list.map(item => (
<div key={item.label}>{item.finish && <span>{item.label}</span>}</div>
))}
</div>
</div>
);
}
}
export default Todo;
复制代码
父组件
import todoStore from '../store/todo';
<Provider todoStore={todoStore} >
<Todo />
</Provider>
复制代码
inject的方式有个缺点,typescript支持不太好,注入之后还得手动写props的类型,体验一般
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END