mobx 学习:core - 可观察状态(Observable state)
对 makeObservable/makeAutoObservable/observable 几个 api 的学习
属性,完整的对象,数组,Maps 和 Sets 都可以被转化为可观察对象。 使得对象可观察的基本方法是使用 makeObservable 为每个属性指定一个注解
makeObservable
这个函数可以捕获已经存在的对象属性并且使得它们可观察
makeObservable(target, annotations?, options?)
常用的注解如下
observable
定义一个存储 state 的可追踪字段。action
将一个方法标记为可以修改 state 的 action。computed
标记一个可以由 state 派生出新的值并且缓存其输出的 getter。
使用示例
import { makeObservable, observable, computed, action } from 'mobx';
class Doubler {
value;
constructor(value) {
makeObservable(this, {
value: observable,
double: computed,
increment: action,
fetch: flow,
});
this.value = value;
}
get double() {
return this.value * 2;
}
increment() {
this.value++;
}
*fetch() {
const response = yield fetch('/api/value');
this.value = response.json();
}
}
makeAutoObservable
makeAutoObservable
就像是加强版的 makeObservable
,在默认情况下它将推断所有的属性。你仍然可以使用 overrides
重写某些注解的默认行为。
推断规则:
- 所有 自有 属性都成为
observable
。 - 所有
get
ters 都成为computed
。 - 所有
set
ters 都成为action
。 - 所有 prototype 中的 functions 都成为
autoAction
。 - 所有 prototype 中的 generator functions 都成为
flow
。(需要注意,generators
函数在某些编译器配置中无法被检测到,如果flow
没有正常运行,请务必明确地指定flow
注解。) - 在
overrides
参数中标记为false
的成员将不会被添加注解。例如,将其用于像标识符这样的只读字段。
observable
observable
注解可以作为一个函数进行调用,从而一次性将整个对象变成可观察的。 source
对象将会被克隆并且所有的成员都将会成为可观察的,类似于 makeAutoObservable
做的那样。 同样,你可以传入一个 overrides
对象来为特定的成员提供特定的注解。
import { observable, autorun, configure } from "mobx";
// 去掉修改 store 时的 warning 提示
configure({ enforceActions: "never", });
const todos = observable([
{ title: "Spoil tea", completed: true },
{ title: "Make coffee", completed: false },
]);
autorun(() => {
console.log(
"Remaining:",
todos
.filter((todo) => !todo.completed)
.map((todo) => todo.title)
.join(", ")
);
});
// 打印: 'Remaining: Make coffee'
todos[0].completed = false;
// 打印: 'Remaining: Spoil tea, Make coffee'
todos[2] = { title: "Take a nap", completed: false };
// 打印: 'Remaining: Spoil tea, Make coffee, Take a nap'
todos.shift();
// 打印: 'Remaining: Make coffee, Take a nap'
setTimeout(() => {
todos[1].completed = true;
}, 1000);
处理深层对象
import { observable, autorun, configure } from "mobx";
configure({ enforceActions: "never" });
const todos = observable(
[
{
title: "Spoil tea",
completed: true,
someDeepObj: {
level1: {
level2: {
level3: "value3",
},
},
},
},
{ title: "Make coffee", completed: false },
],
);
autorun(() => {
console.log(
"Remaining:",
todos
);
});
// 打印: 'Remaining: Make coffee'
setTimeout(() => {
todos[0].someDeepObj.level1.level2.level3 = "abc";
}, 1000);