Mobx6 中文文档 - 翻译计划之observable

创建可观察状态

属性,整个对象,数组,映射和集合都可以被观察到。使对象可观察的基础是使用 makeObservable来为每个属性指定一个注释 。最重要的注释是:

  • observable 定义存储状态的可跟踪字段。
  • action 将方法标记为将修改状态的操作。
  • computed标记一个将从状态中获取新事实并缓存其输出的获取器。

数组,地图和集合之类的集合将自动变为可观察的。

makeObservable

用法:

makeObservable(target, annotations?, options?)

它可用于捕获现有对象属性并使它们可观察。任何JavaScript对象(包括类实例)都可以传递到target中。通常makeObservable用于类的构造函数中,其第一个参数为this。该annotations参数将注释映射到每个成员。请注意,在使用decorators时,可以省略annotations参数。

派生信息并接受参数的方法(例如findUsersOlderThan(age: number): User[])不需要任何注释。从响应调用它们时,仍会跟踪其读取操作,但是不会记住它们的输出,以避免内存泄漏。

class + makeObservable

import { makeObservable, observable, computed, action } from "mobx"

class Doubler {
    value

    constructor(value) {
        makeObservable(this, {
            value: observable,
            double: computed,
            increment: action
        })
        this.value = value
    }

    get double() {
        return this.value * 2
    }

    increment() {
        this.value++
    }
}

function + makeObservable

import { makeAutoObservable } from "mobx"

function createDoubler(value) {
    return makeAutoObservable({
        value,
        get double() {
            return this.value * 2
        },
        increment() {
            this.value++
        }
    })
}

请注意,类也可以利用makeAutoObservable。这些示例之间的差异仅说明了如何将MobX应用于不同的编程样式。

observable

import { observable } from "mobx"

const todosById = observable({
   "TODO-123": {
       title: "find a decent task management system",
       done: false
   }
})

todosById["TODO-456"] = {
   title: "close all tickets older than two weeks",
   done: true
}

const tags = observable(["high prio", "medium prio", "low prio"])
tags.push("prio: for fun")

与带有的第一个示例相反makeObservable,它observable支持向对象添加(和删除)字段。这observable非常适合诸如动态键对象,数组,地图和集合之类的集合。

makeAutoObservable

用法:

makeAutoObservable(target, overrides?, options?)

makeAutoObservablemakeObservable类似,因为它会默认推断所有属性。您仍然可以使用overrides来覆盖具有特定注释的默认行为。特别是false可用于将属性或方法完全排除在处理之外。查看上面的代码标签以获取示例。makeAutoObservable 函数比使用makeObservable更紧凑且更易于维护,因为不必明确提及新成员。但是,makeAutoObservable不能用于具有super或subclassed的类。

推理规则:

  • 包含function值的任何(继承的)成员都将用注释autoAction

  • 任何get三元都将带有computed注释。

  • 其他任何自己的字段都将标记为observable

  • 任何(继承的)作为生成器函数的成员都将带有注释flow。(请注意,在某些编译器配置中无法检测到生成器功能,如果流无法按预期运行,请确保flow明确指定。)

  • overrides参数中被标为false的成员将不会被注释。例如,将其用于只读字段(例如标识符)。

    observable

    用法:

    observable(source, overrides?, options?)
    

observable注释也可以作为一个函数调用,使整个对象马上被观察到。该source对象将被克隆,并且所有成员将变为可观察的,类似于makeAutoObservable的方式。同样,overrides可以提供地图以指定特定成员的注释。查看上面的代码块作为示例。

返回的对象observable将是Proxy,这意味着以后添加到该对象的属性也将被拾取并变为可观察(除非禁用了代理用法)。

observable也可以使用集合类型(如数组,地图和集合)调用该方法。这些也将被克隆并转换为可观察的对应对象。

可用的注释

注解 描述
observable observable.deep 定义一个存储状态的可跟踪字段。如果可能的话,任何分配给observable字段的值也将被递归地观察。也就是说,当且仅当值是纯对象,数组,Map或Set时。
observable.ref 类似于observable,但仅会跟踪重新分配。分配的值本身不会自动变为可观察的。例如,如果要将不可变数据存储在可观察字段中,请使用此选项。
observable.shallow 喜欢,observable.ref但用于收藏。分配的任何集合都将变为可观察的,但是集合本身的内容将变得不可观察。
observable.struct 与相似observable,除了任何在结构上等于当前值的赋值都会被忽略。
action 将方法标记为将修改状态的操作。查看操作以获取更多详细信息。
action.bound 与动作类似,但也会将动作绑定到实例,以便this始终进行设置。
computed 可以在getter上使用,以将其声明为可以缓存的派生值。查看计算出的更多详细信息。
computed.struct 与相似computed,除了如果重新计算后的结果在结构上与先前的结果相同,则不会通知任何观察者。
true 推断最佳注释。查看makeAutoObservable以获得更多详细信息。
false 显式不注释此属性。
flow 创建一个flow以管理异步过程。查看流程以获取更多详细信息。请注意,TypeScript中的推断返回类型可能已关闭。
autoAction 不应显式使用,而应makeAutoObservable根据其调用上下文在后台使用,以标记可以充当操作或派生方法的方法。

局限性

  1. make(Auto)Observable仅支持已定义的属性。使用之前,请确保您的编译器配置正确或作为变通方法,即已将值分配给所有属性make(Auto)Observable。没有正确的配置,class X { y; }将无法正确拾取已声明但尚未初始化的字段(如中的)。
  2. makeObservable只能注释由其自己的类定义声明的属性。如果子类或超类引入了可观察字段,则它必须自己调用makeObservable这些属性。
  3. 默认情况下,TypeScript不允许您注释私有字段。可以通过将相关的专用字段显式传递为通用参数来克服,例如:makeObservable<MyStore, "myPrivateField" | "myPrivateField2">(this, { myPrivateField: observable, myPrivateField2: observable })
  4. 调用make(Auto)Observable和提供注释必须无条件完成,因为这样可以缓存推理结果。
  5. 不支持JavaScript私有字段(#field语法)。使用TypeScript时,建议改用private修饰符。

选项

上面的API带有一个可选options参数,该参数是一个支持以下选项的对象:

  • autoBind: true 自动将所有创建的操作绑定到实例。
  • deep: falseobservable.ref默认情况下使用,而不是observable创建新的可观察成员。
  • name: <string> 为对象提供一个调试名称,该名称将打印在错误消息和反射API中。

将可观察变量转换回原始JavaScript集合

有时有必要将可观察的数据结构转换回原始的数据结构。例如,当将可观察对象传递到无法跟踪可观察对象的React组件时,或获得不应进一步突变的克隆时。

要浅转换集合,通常的JavaScript机制起作用:

const plainObject = { ...observableObject }
const plainArray = observableArray.slice()
const plainMap = new Map(observableMap)

简短说明

到目前为止,以上大多数示例都倾向于使用类语法。MobX原则上对此没有限制,并且可能有使用纯对象的MobX用户数量一样多。但是,类的一个小好处是它们具有更容易发现的API,例如TypeScript。此外,instanceof检查对于类型推断确实非常强大,并且类实例也不会包含在内Proxy对象,使他们在调试器中获得更好的体验。最后,类可以从许多引擎优化中受益,因为它们的形状是可以预测的,并且方法在原型上是共享的。但是繁重的继承模式很容易成为foot脚,因此,如果您使用类,请使其保持简单。因此,即使稍微偏爱使用类,我们也绝对希望鼓励您脱离这种风格,如果它更适合您。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容