Computed properties without @computed

The @computed decorator can be used on getter properties of a class to designate them as observables that depend on other observables:

import React from 'react';
import { observable, computed } from 'mobx';
import { observer } from 'mobx-react';

@observer class ParentComponent extends React.Component {
  @observable isLoading = false;
  @observable isSaving = false;
  @computed get active() { return this.isLoading || this.isSaving; }

  render() {
    return (
      <div>
        <Spinner active={this.active}>
      </div>
    );
  }
}

The above works but results in ParentComponent's render method getting re-evaluated whenever the value of the computed changes. What we want to do instead is pass an observable object with active property on it instead but we need that property to be computed, which cannot be done with a @computed decorator as it's not a class.

Luckily, no @computed designation is required to create a computed property, all you need is an observable with a getter property:

import React from 'react';
import { observable } from 'mobx';
import { observer } from 'mobx-react';

@observer class ParentComponent extends React.Component {
  @observable isLoading = false;
  @observable isSaving = false;
  @observable spinnerState = {
    get active() { return this.isLoading || this.isSaving; }
  };

  render() {
    return (
      <div>
        <Spinner observable={this.spinnerState}>
      </div>
    );
  }
}
// Spinner will use props.observable.active to determine if it should render

We have made this observable.active pattern a standard approach in our React components.

Last updated