MobX autorun behavior

家住魔仙堡 提交于 2019-12-22 05:53:23

问题


I'm exploring MobX and went intrigued by a problem:

If I have this observable:

class ItemsStore {
    @observable items = [1,2,3];
}
const store = new ItemsStore;

and then change it like this:

setInterval(() => {
    store.items[0] = +new Date
}, 1000)

I noticed the following:

  • autorun(() => console.log(store.items)); never fires...
  • autorun(() => console.log(store.items[0])); fires every 1s and gives a new value
  • autorun(() => console.log(store.items.length)); fires every 1s although value is unchanged

What is the API logic behind this? I would expect that since store.items never fires, that unchanged properties would behave the same.

And how come MobX knows what code is inside my callback? is it analysing my callback I pass to autorun?


回答1:


console.log(store.items)

An autorun is fired when the observables that were dereferenced in the last autorun are changed. store.items does not dereference any observables. Try store.items.slice() or store.items.toJS() to get the desired effect.

console.log(store.items[0])

This fired because the observable that got dereferenced is changed.

console.log(store.items.length)

This is run because a MobX array is not a real array. The length property is defined as follows:

Object.defineProperty(ObservableArray.prototype, "length", {
    enumerable: false,
    configurable: true,
    get: function(): number {
        return this.$mobx.getArrayLength();
    },
    set: function(newLength: number) {
        this.$mobx.setArrayLength(newLength);
    }
});

getArrayLength reports that the MobX array has been observed:

getArrayLength(): number {
    this.atom.reportObserved();
    return this.values.length;
}


来源:https://stackoverflow.com/questions/41087478/mobx-autorun-behavior

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!