我如何订阅 mobx 中的@computed 对象?

How do I subscribe to @computed object in mobx?

我想订阅一个 属性 计算 returns 一个简单的对象。

Codesandbox:https://codesandbox.io/s/epic-noether-g8g0x

我根据自己的情况做了一个简单的例子来说明问题所在:

const zeroSize = {
    width: 0,
    height: 0
};

class Item {
    @observable size = zeroSize;
}

class Collection {
    @observable childrens: Item[] = [];

    @computed get size() {
        return this.childrens.length > 0 && this.childrens[0] ? this.childrens[0].size : zeroSize;
    }

    constructor() {
        reaction(() => this.size, size => {
            // Expected { width: 0, height: 1000 }
            // Actual { width: 0, height: 0 }
            console.log('-----size=', toJS(size));
        });
    }
}

const item1 = new Item;
const collection1 = new Collection;
collection1.childrens.push(item1);
item1.size.height = 1000;

https://github.com/mobxjs/mobx/issues/2176

您正在监听错误的零钱。

因为你正在监听尺寸变化,所以高度会触发变化:

const item1 = new Item; // size === 0
const collection1 = new Collection; // size === 0
collection1.childrens.push(item1); // size === 1 (triggers reaction)
item1.size.height = 1000; // size === 1 (doesn't trigger reaction)

如果您想收听由 childrens 更改导致的任何和所有更改,那么这就是您需要收听更改的原因。

reaction(
  () => toJS(this.childrens),
  size => {
    // Expected { width: 0, height: 1000 }
    // Actual { width: 0, height: 0 }
    console.log("-----size=", toJS(this.size));
  }
);

通过监听toJS(this.childrens),可以订阅childrens的长度变化,也可以订阅childrens的某个元素的属性变化。

如果您只想听添加或删除新子项的时间,那么听 size 是有意义的。如果您想在添加、删除或修改子项时收听,则需要更改您正在收听的内容。

这是一个沙箱:https://codesandbox.io/embed/white-hill-fntxt

以及相关的控制台日志:

-----size= Object {width: 0, height: 0}
-----size= Object {width: 0, height: 1000}