MobX Recipes
  • Introduction
  • Observable vs @observable
  • Auto-save
  • Use extendObservable sparingly
  • Use observables instead of state in React components
  • Computed properties without @computed
  • Use computed.struct for computed objects
  • Observable-based routing
  • Be aware of short-circuited code in reactions
Powered by GitBook
On this page

Was this helpful?

Computed properties without @computed

PreviousUse observables instead of state in React componentsNextUse computed.struct for computed objects

Last updated 4 years ago

Was this helpful?

The 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.

@computed