Categories
Mobx

List of MobX Modifiers

Spread the love

MobX has a set of decorators to change how observable properties will behave.

In this article, we’ll look at them one by one and see how we can use them.

Modifiers

MobX comes with the following decorators that defines how observable properties will behave:

  • observable — an alias for observable.deep
  • observable.deep — the default modifier used by any observable. It clones and converts any array, map or plain object into its observable counterpart
  • observable.ref — disables automatic observable conversion and creates an observable reference instead
  • observable.shallow — can only be used with collections. Turns any assigned collection into an observable, but the values will be treated as-is
  • observable.struct — like ref but ignore new values that are structurally equal to the current value
  • computed — creates a derived property
  • computed(options) — same as computed , but sets additional options
  • computed.struct — same as computed , but only notify any of is observers when the value produced is structurally different from the previous value.
  • action — creates an action
  • action(name) — creates action and overrides the name
  • action.bound — creates action and binds this to the instance.

Decorators can be used the MobX’s decorate , observable.object , extendObservable and observable to specify how object members should behave.

observable.deep is the default behavior for any key-value pair by default and computed for getters.

For example, we can define an observable as follows:

import { observable, action } from "mobx";

const person = observable(
  {
    firstName: "John",
    lastName: "Smith",
    age: 42,

  get fullName() {
      return `${this.firstName} ${this.lastName}`;
    },

  setAge(age) {
      this.age = age;
    }
  },
  {
    setAge: action
  }
);

In the code above, we have the default decorators for all members except for setAge , which we explicitly defined as an action .

Therefore, firstName , lastName , and age are observable s and fullName is a computed field.

We can use the decorate function as follows:

import { observable, action, decorate } from "mobx";

class Person {
  firstName = "John";
  lastName = "Smith";
  age = 42;

  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }

  setAge(age) {
    this.age = age;
  }
}

decorate(Person, {
  firstName: observable,
  lastName: observable,
  age: observable,
  setAge: action
});

In the code above, we call decorate with the class as the first argument, and then an object with the fields we want to modify as the second argument.

We set firstName , lastName and age as observables and setAge as an action.

fullName is a computed field since it’s the default option for getters.

Deep Observability

When MobX creates an observable object using observable , observable.object or extendObservable , it introduces observable properties which use the deep modifier by default.

The deep modifier recursively calls observable(newValue) for any assigned value which uses the deep modifier until it gets to the bottom level of the object.

Reference Observability

In some cases, objects don’t need to be converted into observables. For example, we don’t want to do this for immutable objects or objects that are managed by an external library.

In this case, we can use the ref modifier.

For example, we can use it as follows:

class Person {
  firstName = "John";
  lastName = "Smith";
  @observable.ref age = 42;
}

In the code above, we added the observable.ref decorator to age so that MobX will only track its reference but doesn’t try to convert its value.

With ES5 syntax, we can write the following:

import { observable, extendObservable } from "mobx";

function Person() {
  extendObservable(
    this,
    {
      name: "Joe",
      age: 42
    },
    {
      age: observable.ref
    }
  );
}

Shallow Observability

We can use the observable.shallow modifier to apply observability one level deep. We need this to create a collection of observable references.

It won’t recursively apply observability like deep .

For example, we can use it as follows:

class Books {
  @observable.shallow authors = [];
}

{ deep: false } can be passed as an option to observable , observable.object , observable.array , observable.map , and extendObservable to create shallow collections.

Conclusion

We can use modifiers to change the way MobX watches the changes in the values.

The default is that it looks at a value recursively for changes.

There’re also modifiers for computed values, shallow watch, and more.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *