hanyuxinting / Blog

记录点滴
1 stars 0 forks source link

React学习-Redux VS Mobx(关注Mobx) #35

Open hanyuxinting opened 5 years ago

hanyuxinting commented 5 years ago

Mobx

入门了解

通过透明的函数响应式编程(transparently applying functional reactive programming - TFRP)使得状态管理变得简单和可扩展。

tu

React 和 MobX 是一对强力组合。React 通过提供机制把应用状态转换为可渲染组件树并对其进行渲染。而MobX提供机制来存储和更新应用状态供 React 使用。 React 提供了优化UI渲染的机制, 这种机制就是通过使用虚拟DOM来减少昂贵的DOM变化的数量。 MobX 提供了优化应用状态与 React 组件同步的机制,这种机制就是使用响应式虚拟依赖状态图表,它只有在真正需要的时候才更新并且永远保持是最新的。

MobX 要点

核心概念

Observable state(可观察的状态)

为现有的数据结构(如对象,数组和类实例)添加了可观察的功能; 通过使用 @observable 装饰器(ES.Next)来给你的类属性添加注解就可以简单地完成这一切。

import { observable } from "mobx";

class Todo {
    id = Math.random();
    @observable title = "";
    @observable finished = false;
}

Computed values(计算值)

定义在相关数据发生变化时自动更新的值。 通过@computed 装饰器或者利用 (extend)Observable 时调用 的getter / setter 函数来进行使用。

class TodoList {
    @observable todos = [];
    @computed get unfinishedTodoCount() {
        return this.todos.filter(todo => !todo.finished).length;
    }
}

Reactions(反应)

Reactions 和计算值很像,但它不是产生一个新的值,而是会产生一些副作用,比如打印到控制台、网络请求、递增地更新 React 组件树以修补DOM、等等。 简而言之,reactions 在 响应式编程和命令式编程之间建立沟通的桥梁。

React 组件

React 下,可以把(无状态函数)组件变成响应式组件,方法是在组件上添加 observer 函数/ 装饰器. observer由 mobx-react 包提供的。

observer 会将 React (函数)组件转换为它们需要渲染的数据的衍生。

自定义 reactions

使用autorun、reaction 和 when 函数即可简单的创建自定义 reactions,以满足你的具体场景。 如:unfinishedTodoCount 的数量发生变化时,下面的 autorun 会打印日志消息:

autorun(() => {
    console.log("Tasks left: " + todos.unfinishedTodoCount)
})

Actions(动作)

装饰符语法的例子

需要设置和编译,目前只有 Babel/Typescript 编译器支持

// 装饰符语法
import { observable, computed, action } from "mobx";

class Timer {
  @observable start = Date.now();
  @observable current = Date.now();

  @computed
  get elapsedTime() {
    return this.current - this.start + "milliseconds";
  }

  @action
  tick() {
    this.current = Date.now();
  }
}

装饰器语法的优劣性: 优势:

劣势:

使用装饰器的两种方式

上代码同:

import { observable, computed, action, decorate } from "mobx";

class Timer {
    start = Date.now();
    current = Date.now();

    get elapsedTime() {
    return this.current - this.start + "milliseconds";
  }

    tick() {
        this.current = Date.now()
    }
}
decorate(Timer, {
    start: observable,
    current: observable,
    elapsedTime: computed,
    tick: action
})

mobx-react 中的observer 函数既是装饰器也是函数:

@observer
class Timer extends React.Component {
    /* ... */
}

const Timer = observer(class Timer extends React.Component {
    /* ... */
})

const Timer = observer((props) => (
    /* 渲染 */
))
启用装饰符语法

.babelrc:

{
  "presets": ["mobx"]
}

3) 要启用装饰器的支持而不使用 mobx preset

npm i --save-dev babel-plugin-transform-decorators-legacy
{
  "presets": ["es2015", "stage-1"],
  "plugins": ["transform-decorators-legacy"]
}
MobX 社区并没有正式支持以下模式: