We've looked at creating Observable properties, which let us watch for changes in our Application State. But how do our Components track those changes?

If you look at the UserView.render method, we simply read from our User. MobX tracked those changes for us automatically using Computed properties. For our Components, this is done behind the scenes. But we can use them in our Application State just as easily.

Computed Properties

MobX provides Computed properties for objects, which use a getter function to produce a value. However, any Observable properties used in this function, will automatically produce subscriptions.

For simplicity, we can also use the @computed decorator, except in front of a getter function.

@computed get property(): type {
    return this.value;
}

For our User let's add a fullName Computed property. Add this right under the firstName and lastName properties.

@computed get fullName() {
    return this.firstName + ' ' + this.lastName;
}

Then in our UserView, let's add the line

<p>Full name: {user.fullName}</p>

There are a couple things to note:

  1. We simply used the values in order to subscribe to them automatically.
  2. We can use as many values as we want.
  3. Whatever we return from this method will be the value of the property.

Avoid Circular References

In order for updates to flow, we must avoid any "circular references" or "cycles". This means that as an update is occurring, it must not reach the same node more than once.

For example, let's say we have two Computed properties, A and B. And let's say A references B, and B references A. So if A is updated, then we must update B. Similarly if B is updated, we must update A. In which case updating A, will update B, which will update A, which will update B, and so on.

So it is important that these situations be avoided.

Responding to updates

It is best to avoid writing to Observable properties inside of a Computed. In most cases, a second Computed which references the first will be enough.

If you must write to an Observable or do other work, it is best to wrap it inside of a window.setTimeout(), or use: