Можно ли создать наследство между двумя магазинами mobx?

Я создаю два виджета с MOBX / реагировать, где вся логика находится внутри магазинов. Оба придерживаются большинства правил дизайна, поэтому их магазины идентичны на 95%. Есть ли умный способ справиться с этой ситуацией? Например, возможно ли создать такое наследование?

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;
  }  
}

3 ответа

Я знаю, что об этом уже давно спрашивали, но в соответствии с документами здесь вы можете переопределить, как вы написали. Однако есть ограничения :

  1. Только действие, вычисление, поток, action.bound, определенное в прототипе, может быть переопределено подклассом.
  2. Поле не может быть повторно аннотировано в подклассе, кроме как с переопределением.
  3. makeAutoObservable не поддерживает создание подклассов.
  4. Расширение встроенных функций (ObservableMap, ObservableArray и т. д.) не поддерживается.
  5. Вы не можете предоставить другие параметры для makeObservable в подклассе.
  6. Вы не можете смешивать аннотации/декораторы в одной цепочке наследования.
  7. Также применяются все их стандартные ограничения , которые я не буду здесь перечислять.

Это также работает с синтаксисом без аннотаций (например, makeObservable).

Да, вы можете, но вы должны структурировать его следующим образом, используя новый шаблон Mobx, который не использует декораторы:

(Используя машинопись)

      
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;
  }  
}

Если вам нужен экземпляр Animal в вашем приложении, Mobx-State-Tree — лучший вариант. Потому что дважды сделать проп наблюдаемым/действующим/вычисляемым (родительский класс и подкласс) вызовет ошибку.

Рассматривали ли вы MobX State Tree ( https://github.com/mobxjs/mobx-state-tree) для управления двумя вашими классами Animal а также Dog?

Это даст вам мощный compose функциональность, которую можно использовать вместо наследования.

Вот, пожалуй, самая полезная часть для вас: "Имитация наследования с использованием композиции типов" https://github.com/mobxjs/mobx-state-tree

Другие вопросы по тегам