0

I have the following code: It works fine if _isFavorite variable is public observable. But once I change it to @computed, it triggers only once. But further @action callings don't trigger @computed.

This works fine, once isFarovite is changed:

class Cat {
    @observable public isFavorite = false;

    constructor() { ... }

    @action public toggleFavorite() {
        this.isFavorite = !this.isFavorite;
    }
}

This doesn't work if _isFavorite is changed:

class Cat {
    private _isFavorite = false;

    constructor() { ... }

    @computed public get isFavorite() {
        return this._isFavorite;
    }

    @action public toggleFavorite() {
        this._isFavorite = !this._isFavorite;
    }
}

I think I might miss the core concept of how "computed" works, but I can't figure out how I should change my code...

Svyat
  • 82
  • 2
  • 9

1 Answers1

1

This because computed value should be applied on some observables.

It actually checks which observables are used inside of it, and register itself as an observer of it & caches the result.

class Cat {
    @observable private _isFavorite = false;

    constructor() { ... }

    @computed public get isFavorite() {
        return this._isFavorite;
    }

    @action public toggleFavorite() {
        this._isFavorite = !this._isFavorite;
    }
}
felixmosh
  • 32,615
  • 9
  • 69
  • 88
  • Thank you! Indeed works. It wasn't obvious to me to mark a private variable as `@observable` because it is not used directly in render() method. – Svyat Jan 29 '20 at 08:28
  • 1
    It is not related to private / public but to the fact that it was used in observers, as I've explained, `computed` is the same as `observer` on a component :] – felixmosh Jan 29 '20 at 08:51