mobx学习笔记

2019-10-09  本文已影响0人  mah93

安装

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就是用来修饰改变观察值的函数。

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下的子目录结构是相似的或者是相同的,刚接触的时候容易搞混。当功能变动,或者是整体迁移的时候,涉及页面零散不易拆分。

以模块为标准划分

文件夹按照一个个页面功能划分,如首页、注册登录模块、我的模块等,每个文件夹下存放该模块的页面、逻辑等所有涉及到该模块的代码。

这样的划分的好处是,文件结构可以与设计的页面对应起来。划分出一个个独立的模块,实现该模块的所有或者说大部分的代码都在同一个文件夹,易于拆分。

但当模块与模块之间有交互或者跳转的时候,就会横跨几个文件夹,难以对照。又或者模块之间有共用组件的时候就变得十分难以划分。无论将共用组件放到哪里,都不合适。放在其中一个模块中,另一个模块去引用的时候十分困难。两边都放上代码,但是十分麻烦。要是再用一个与模块同级的文件夹,那各个模块又不能真正“独立”起来。

上一篇下一篇

猜你喜欢

热点阅读