安装
npm install mobx --save
配合React: npm install mobx-react --save
概述
MobX 是一个通过对开发者透明的函数响应式编程(TFRP)方式,让状态管理(state management)变得简单、具有高扩展性的库,并且这个库经过了严格的测试。
MobX的思想非常简单:来源于应用的状态的任何事物,都能被自动获得。
包括UI、数据变更、与服务器通信等等。
flow.png核心概念
可观察的状态(observable state)
MobX 给已有的数据结构增加了可观察的能力(如对象、数组、类实例等)。你只需要很简单地使用@observable 装饰你的类属性(property)即可。
class Todo {
id = Math.random();
@observable title = "";
@observable finished = false;
}
计算值(Computed values)
使用 MobX,你可以很容易的定义计算值,当相关数据变化时,计算值会自动发生变化。 计算值可以通过使用 @computed
装饰器声明,也可以通过 (extend)Observable
配合 getter/setter 函数进行声明。
class TodoList {
@observable todos = [];
@computed get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.finished).length;
}
}
MobX 会确保当一个 todo 增加或者当 finished
改变时, unfinishedTodoCount
是自动更新的。 计算值类似于电子表格程序的公式。它们的更新永远是自动的,并且只在需要的时候更新。
@observer
observer
函数/装饰器可以用来将 React 组件转变成响应式组件。当被监听的变量更改的时候,引用到该变量的组件会相应重新渲染。
当组件之间有嵌套情况的时候,向子组件传递的是引用,而不是该引用的值。
action (动作)
用法:
action(fn)
action(name, fn)
@action classMethod() {}
@action(name) classMethod () {}
@action boundClassMethod = (args) => { body }
@action(name) boundClassMethod = (args) => { body }
@action.bound classMethod() {}
@action.bound(function() {})
任何应用都有动作。动作是任何用来修改状态的东西。 action就是用来修饰改变观察值的函数。
mobx还有很多其他的函数以及方法,这里只介绍了其中最常用的四个,其他的功能可以在 mobx官网 中查看。
应用
下面是一个简单的mobx应用,一个父组件包含着两个子组件。当其中一个子组件发生改变时,不会触发另一个组件的重新渲染,从而达到了我们的预期需求:只有发生改变的地方需要重新渲染。实际开发的时候只需要将可能会发生改变的组件独立出来,每次只更新一个组件或几个组件。尽可能减少render函数的负担,提高react-native的重绘能力。
class MyState {
@observable num1 = 0;
@observable num2 = 100;
@action addNum1 = () => {
this.num1 ++;
};
@action addNum2 = () => {
this.num2 ++;
};
}
const newState = new MyState();
const AllNum = observer((props) => {
console.log('刷新all');
return (
<View>
<Text>num2 = {props.store.num2}</Text>
<View>
<Button onPress={props.store.addNum2} title="button2" />
</View>
</View>
);
});
const Main = observer((props) => {
console.log('刷新main');
return (
<View>
<Text>num1 = {props.store.num1}</Text>
<View>
<Button onPress={props.store.addNum1} title="button1" />
</View>
</View>
);
});
@observer
export default class Asset extends PureComponent {
render() {
return (
<View>
<Main store={newState} />
<AllNum store={newState} />
</View>
);
}
}
引入mobx做为项目的数据管理,势必会带来代码量增加等问题。我们可以在项目目录结构上作出相应调整,以便于更好的开发。
以功能为标准划分
将文件夹按照功能区分,比如pages下存放所有的页面,logics下存放所有的mobx的逻辑等。
这样的结构可以一眼就划分出每个js的功能,每个文件夹下存放着相同功能的js。
带来的问题就是,页面与逻辑不在一个地方。查找起来十分麻烦,pages下的子目录与logics下的子目录结构是相似的或者是相同的,刚接触的时候容易搞混。当功能变动,或者是整体迁移的时候,涉及页面零散不易拆分。
以模块为标准划分
文件夹按照一个个页面功能划分,如首页、注册登录模块、我的模块等,每个文件夹下存放该模块的页面、逻辑等所有涉及到该模块的代码。
这样的划分的好处是,文件结构可以与设计的页面对应起来。划分出一个个独立的模块,实现该模块的所有或者说大部分的代码都在同一个文件夹,易于拆分。
但当模块与模块之间有交互或者跳转的时候,就会横跨几个文件夹,难以对照。又或者模块之间有共用组件的时候就变得十分难以划分。无论将共用组件放到哪里,都不合适。放在其中一个模块中,另一个模块去引用的时候十分困难。两边都放上代码,但是十分麻烦。要是再用一个与模块同级的文件夹,那各个模块又不能真正“独立”起来。
网友评论