Like Danila mentions, you are likely hitting the change in MobX v6 where you have to explicitly make each class-instance observable, by calling makeObservable
or makeAutoObservable
in the class constructor:
class ExampleStore {
constructor() {
makeObservable(this);
}
@observable email = "hello";
[...]
}
I'm not really a fan of the change though. It's not so much about the extra step of adding a constructor + function-call (for classes that otherwise don't need it); it has more to do with that it means I always have to "check the class" to make sure I've added the "activation call" for the field decorators I've added. In other words, it splits the "make this field observable" action into two parts, which sometimes are separated by substantial distances.
So anyway, my solution for this is to wrap the @observable
decorator, and have it check the constructor's source-code to ensure that the call is being made: (performance impact is virtually nothing since it only runs when defining the class)
const observableWarningGivenFor = new WeakSet<Function>();
export const obs = ((target: Object, propertyKey: string | symbol)=>{
if (target.constructor instanceof Function && !target.constructor.toString().includes("makeObservable")) {
if (!observableWarningGivenFor.has(target.constructor)) {
console.warn(`The @obs decorator was used on "`
+ target.constructor.name + "." + String(propertyKey)
+ `", but the class is missing the "makeObservable(this);" call.`
+ ` See here for more info: https://mobx.js.org/enabling-decorators.html`);
observableWarningGivenFor.add(target.constructor);
}
}
return observable(target, propertyKey);
}) as typeof observable;
// copy ".ref", etc. fields from "observable" (not wrapped)
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(observable))) {
Object.defineProperty(obs, key, descriptor);
}
Usage: (same as normal)
class ExampleStore {
constructor() {
makeObservable(this);
}
@obs email = "hello";
[...]
}
The only difference is that now, if I forget to add the makeObservable(this);
call for a class that I added an @obs
decorator for, I get a warning message.