This is my simplified store:
export class ProfileStore {
profile = {
id: 1,
name: "Tommy",
todos: [
{
value: "Clean the room",
done: false
}
]
};
constructor() {
makeObservable(this, {
profile: observable,
});
}
}
My goal is to listen to every possible change inside "profile" observable.
I wanted to use reaction
from MobX for this but it is kinda tricky.
reaction(
() => this.profile,
() => {
console.log("change");
}
);
Above example doesn't work at all because MobX doesn't react to values but to properties and references. So I changed it to this:
reaction(
() => ({
id: this.profile.id,
name: this.profile.name,
todos: this.profile.todos.slice()
}),
() => {
console.log("change");
}
);
And it started working but not entirely. It listened to every change besides toggling done
property in todos. And if I add another property I would need to list in here which is kinda tedious.
What's the best way to handle this problem? How to react to every possible change?
I made a codesandbox for this: link
Try to press buttons and look at the counter.
To react for every possible change you need to dereference every property. To do that, for example, you can use toJS
method to serialize your profile
object. (Or even native JSON.stringify
):
import { reaction, toJS } from 'mobx';
// ...
reaction(
() => toJS(profileStore.profile),
() => {
setReactionCounter((state) => state + 1);
}
);