V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
kuanng
V2EX  ›  JavaScript

mobx 使用求助

  •  
  •   kuanng · 2020-03-09 19:00:17 +08:00 · 1731 次点击
    这是一个创建于 1719 天前的主题,其中的信息可能已经有所发展或是发生改变。

    89Qg3j.png

    这个 total 应该是 computed 的,那为什么没有缓存值呢?

    是我理解错了么?

    9 条回复    2020-03-09 19:56:49 +08:00
    noe132
        1
    noe132  
       2020-03-09 19:13:25 +08:00 via Android
    0 * 1 不等 0 么?
    noe132
        2
    noe132  
       2020-03-09 19:15:02 +08:00 via Android
    理解错了。。
    ddzy
        3
    ddzy  
       2020-03-09 19:18:33 +08:00
    没看懂
    kuanng
        4
    kuanng  
    OP
       2020-03-09 19:23:00 +08:00
    @ddzy 照我的理解:total 是一个 computed,它依赖于 price 和 amount。所以在 price 和 amount 没有改变下,total 的计算值被缓存起来,这样的话控制台不应该打印三次的 ff
    noe132
        5
    noe132  
       2020-03-09 19:25:24 +08:00
    这个缓存只会在 when / autorun / reaction / 其他 computed 中被使用。
    const state = observable({
    a:1,
    b:2,
    c:3,
    get d(){ console.log('computed'); return this.a * this.b }
    })

    m.reaction(() => temp3.c + temp3.d, () => { console.log('reaction')})

    state.a = 3
    // log reaction + run
    state.c = 5
    // log reaction
    noe132
        6
    noe132  
       2020-03-09 19:40:50 +08:00
    https://mobx.js.org/refguide/computed-decorator.html

    that if you create a computed property but don't use it anywhere in a reaction, it will not cache its value and recompute more often than seems necessary

    when / autorun / reaction 会假设你的依赖是除了包含 reactive 值的其他部分是不包含任何副作用的,所以会缓存,而在这些之外手动访问,可能不能保证不产生副作用。类似如果写出像这样的 getter:

    get d() { return [Date.now()] }

    是否每次时间变化都会触发 autorun ?结果显然是不会,因为 Date.now()并不是 reactive 的。而 get d() 却并不是一个纯函数。

    如果希望函数执行的结果每次都能缓存下来,需要自己封装一层,通过 reaction 将结果缓存下来,类似下面这样
    const useMobxMemo = (computedFunction) => {
    const value = computed(computedFunction);
    const state = {
    value,
    };

    reaction(() => value.value, () => {
    state.value = value.value;
    });

    return state.value;
    };
    momocraft
        7
    momocraft  
       2020-03-09 19:43:33 +08:00
    class + decorator 的写法应该会缓存的

    observable.object 会自动把 getter 转为 computed 吗?
    kuanng
        8
    kuanng  
    OP
       2020-03-09 19:53:15 +08:00
    @noe132 的确,在 autorun 中有缓存了。谢了
    kuanng
        9
    kuanng  
    OP
       2020-03-09 19:56:49 +08:00
    @momocraft 文档中,会自动变为 computed
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2189 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:03 · PVG 08:03 · LAX 16:03 · JFK 19:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.