mobx & mobx-react

State(状态)

属性,完整的对象,数组,Maps 和 Sets 都可以被转化为可观察对象。 使得对象可观察的基本方法是使用 makeObservable 为每个属性指定一个注解。 最重要的注解如下:

  • observable 定义一个存储 state 的可追踪字段。

  • action 将一个方法标记为可以修改 state 的 action。

  • computed 标记一个可以由 state 派生出新的值并且缓存其输出的 getter。

参考:Creating observable state · MobX

Action(动作)

所有的应用程序都有 actions。action 就是任意一段修改 state 的代码。原则上,actions 总会为了对一个事件做出响应而发生。例如,点击了一个按钮,一些输入被改变了,一个 websocket 消息被送达了,等等。

Derivations(派生)

任何 来源是State(状态) 并且不需要进一步交互的东西都是 Derivation(派生)。

Derivations 包括许多方式:

  • 用户界面

  • 派生数据 , 比如剩余未完成todos的数量

  • 后端集成 , 比如发送改变到服务器端

Mobx 区分了两种 Derivation :

  • Computed values,总是可以通过纯函数从当前的可观测 State 中派生。

  • Reactions, 当 State 改变时需要自动运行的副作用 (命令式编程和响应式编程之间的桥梁)

computed

类似于 Excel 单元格中的公式,依赖observable state变化而重新更新

reactions

Reaction 和 computed 类似,但并不产生信息,而是产生副作用,如打印到控制台、发出网络请求、增量更新 React 组件树以便更新DOM等

简单例子

import React from "react"
import ReactDOM from "react-dom"
import { makeAutoObservable } from "mobx"
import { observer } from "mobx-react"

// 对应用状态进行建模。
class Timer {
  secondsPassed = 0

  constructor() {
    makeAutoObservable(this)
  }

  increase() {
    this.secondsPassed += 1
  }

  reset() {
    this.secondsPassed = 0
  }
}

const myTimer = new Timer()

// 构建一个使用 observable 状态的“用户界面”。
const TimerView = observer(({ timer }) => (
  <button onClick={() => timer.reset()}>已过秒数:{timer.secondsPassed}</button>
))

ReactDOM.render(<TimerView timer={myTimer} />, document.body)

// 每秒更新一次‘已过秒数:X’中的文本。
setInterval(() => {
  myTimer.increase()
}, 1000)

更新流程

整体模型如下:

模型:src/ide/designer/src/project/project.ts

视图:src/ide/designer/src/project/project-view.tsx