7

I'm building two widgets with mobx/react, where all the logic sits inside the stores. Both share most of the design rules, so their stores are 95% identical. Is there a smart way to handle this situation? For example, is it possible to create inheritance such as this?

class Animal { 
  @observable name = "";

  constructor(name) {
    this.name = name;
  }

  @computed get sentence() {
    console.log(this.name + ' makes a noise.');
  }
}

class Dog extends Animal {
  @observable isBarking = false;
  @computed get bark() {
    if (this.isBarking){
        console.log('The dog is barking');
    }
  }
  @action
    setIsBarking(isBarking) {
    this.isBarking = isBarking;
  }  
}
Sveta
  • 1,041
  • 13
  • 22

3 Answers3

1

Yes you can, but you have to structure it like this, using the new Mobx pattern which does not use decorators:

(Using Typescript)


import {observable, action, computed, makeObservable} from "mobx";

const animalProps = {
   name: observable,
   sentence: computed
};

class abstract Animal { 
  name = "";

  constructor(name) {
    this.name = name;
  }

  get sentence() {
    console.log(this.name + ' makes a noise.');
  }
}

class Dog extends Animal {
  
   isBarking = false;

   constructor(){
     makeObservable(this, {
       ...animalProps,
       isBarking: observable,
       bark: computed,
       setIsBarking: action
     });
   }
  
   get bark() {
    if (this.isBarking){
        console.log('The dog is barking');
    }
  }

    setIsBarking(isBarking) {
       this.isBarking = isBarking;
  }  
}

If you need an instance of Animal in your app, then Mobx-State-Tree is a better option. Because making a prop observable/actionable/computable twice (the parent class and the subclass) will throw an error.

DeltaTango
  • 821
  • 2
  • 9
  • 19
1

I know this was asked a long time ago at this point, but per the docs here you can override as you wrote. There are limitations though:

  1. Only action, computed, flow, action.bound defined on prototype can be overriden by subclass.
  2. Field can't be re-annotated in subclass, except with override.
  3. makeAutoObservable does not support subclassing.
  4. Extending builtins (ObservableMap, ObservableArray, etc) is not supported.
  5. You can't provide different options to makeObservable in subclass.
  6. You can't mix annotations/decorators in single inheritance chain.
  7. All their standard limitations apply as well which I won't list here.

This works with the non-annotation syntax as well (e.g., makeObservable).

stuckj
  • 977
  • 1
  • 13
  • 24
0

Have you consider MobX State Tree (https://github.com/mobxjs/mobx-state-tree) for managing your two classes Animal and Dog ?

This will give you the powerfull compose functionality, that could be used instead of inheritance.

Here's the probably most useful part for you: "Simulate inheritance by using type composition" https://github.com/mobxjs/mobx-state-tree#simulate-inheritance-by-using-type-composition

maxgallo
  • 458
  • 3
  • 14