Mobx工作记录
之前由于项目比较急,需要在短时间内学习并上手mobx,虽然已经用react+mobx开发了好几个项目,一直都没时间总结一下。特此梳理一下,让知识沉淀沉淀~
Mobx官方文档
Mobx官方中文文档
Mobx的核心概念
Mobx的核心原理是通过action触发state的变化,进而触发state的衍生对象(computed value & Reactions)。
1.State(状态)
其实就是我们需要用Mobx管理起来的数据。
在Mobx中,State就对应业务的最原始状态,通过observable方法,可以使这些状态变得可观察。
值得注意的一点是,当某一数据被observable包装后,他返回的是被observable包装后的类型。
2.Action(动作)
动作 是任一一段可以改变状态的代码。用户事件、后端数据推送、预定事件、等等。 动作类似于用户在excel单元格中输入一个新的值。 我们的异步请求都可以在这里做。但是这里要注意一点,异步的函数里面对state的更改是不能检测到的。所以异步的回调也需要用action()包一下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class demoMobx {
@action getServerList = (id) => { this.send(api_url, action(res => { })); }
}
|
这里还有一个 flow
需要讲一下:
- 用法: flow(function* (args) { }),
flow() 接收 generator
函数作为它唯一的输入,当处理异步动作时,回调中执行的代码不会被 action 包装。这意味着你修改的 observable state 无法通过 enforceActions 检查。保留动作语义的简单方法是使用 flow 来包装异步函数。这将确保所有回调都会被 action() 包装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import { configure } from 'mobx';
configure({ enforceActions: true });
class Store { @observable githubProjects = []; @observable state = "pending";
fetchProjects = flow(function* fetchProjects() { this.githubProjects = []; this.state = "pending"; try { const projects = yield fetchGithubProjectsSomehow(); const filteredProjects = somePreprocessing(projects);
this.state = "done"; this.githubProjects = filteredProjects; } catch (error) { this.state = "error"; } }) }
|
3. Derivations(衍生)
这一部分的概念一直不是太理解,工作之中也不能直观的感受到它,一直迷迷糊糊。但是又感觉不影响正常开发,这里只能先留一个TODO,等啥时候脑子开窍了,再来补上吧~
:smile:
在React项目中使用Mobx
1.将store注入到全局
mobx-react
提供了 Provider
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'mobx-react'; import App from './app/app';
import stores from '../../modules/store';
export function baseReact() { return ( <Provider {...stores}> <App/> </Provider> ); }
ReactDOM.render(baseReact(), document.getElementById('skin'));
|
2.mobx在store和组件里的应用;
mobx-react
提供了reject
和 observer
两个工具去把store和组件关联起来。
reject
是将该组件的store注入进来;
observer
可以用作包裹 React 组件的高阶组件, 在组件的 render 函数中的任何已使用的 observable 发生变化时,组件都会自动重新渲染。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { BaseStore } from "../../../../../component.index"; import { observable, action} from "mobx";
class DesignRightStore extends BaseStore {
@observable rightComponentTabIndex: number = 0; @observable showBackgroundColorPicker: boolean = false;
@action setRightComponentTabIndex = (index: number) => { this.rightComponentTabIndex = index; }
}
export default new DesignRightStore();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import React from 'react'; import { withRouter } from "react-router"; import { inject, observer} from "mobx-react";
@withRouter @inject('DesignRightStore') @observer class DesignElementPanel extends React.Component {
constructor(props){ super(props); }
render(){ return( <div> {/*组件内可以通过 this.props.DesignRightStore 拿到store里面的值和方法*/} {this.props.DesignRightStore.rightComponentTabIndex} </div> ) }
}
export default DesignElementPanel;
|