mobx带来的响应式编程和可变数据结构笔记剪藏(2015,Michel Westavenue)

975 阅读2分钟

代码

以下描述了类,以及依赖于类的一个指针变量

// arrays
const store = {
 boxes:[],
  arrrows:[],
  selection:null
};
// classes
store.boxes.push(
 new Box('Rotterdam',100,100),
 new Box('Vienna',700,150),
);

store.arrows.push({
 id:randomUuild(),
  from:store.boxes[0],
  to:store.boxes[1],
})

Box的定义

class Box{
  id = randomUuid();
  @observable name = 'a box';
  @observable x = 0 ; 
  @observable y = 0 ; 
  @observable get width(){
   return this.name.length * 15;
  }
  constructor(name,x,y,id){
   this.name = name ; 
    this.x = x ; 
    this.y = y ;
    this.id = id || randomUuid();
  } 
}

不可变数据结构 vs 可变的数据结构

不可变数据结构响应式可变数据结构
不会改变身份平等
结构固定概念在内存中应该仅存在一次
方便记忆,结构共享,没防御性拷贝,时间旅行总是最新的
假设数据是一个树,不是一个图组合和关联
非规范化其余部分原型和类型检查
自然的心智模型
简单的行为模式

可观察性 @observer

  • mobservable.autorun(()=>this.render())
  • autorun
    • 引入一个方法,实现响应式
    • 每次执行之后,运行时订阅数据可触达性
    • 数据变化时重新执行
    • 可控的依赖树
  • 单纯的渲染混合函数

对比流程

改变 actions

  • 直接的数据改变
  • 不需要有上下文的意识
  • 没有标准的模板需要遵循

其他的

时间旅行

autorun函数中使用serializeState 来存储(跟踪)所有的读写记录

const state = [] ;

autorun(()=>{

states.push(serializeState(store));

})

热加载

if(module.hot){
 module.hot.accept();
  if(module,hot.data && module.hot.data.store){
   deserializeState(store,module.hot.data.store);
  }
  module.hot.dispose(data=>{
   data.store = serializeState(store);
  })
}

核心api

@observable让成员变为响应式
autorun创造一个字更新函数,使用响应式数据
@observer封装react组件的render方法在autorun函数中

如何底层实现的

  • 装饰 所有的对象属性和数组指针
  • 在栈中存储视图相关
  • 数据读取注册到观察者
  • 数据设置通知观察者

image.png

依赖树分析

  • 订阅随时间改变

  • 同步更新,支持事务机制

  • 原子粒度的更新

  • 循环检测

  • 非纯视图的函数检测

  • 懒汉和饿汉评估模式

  • 垃圾回收

原文

我的语雀原文