'Detect when mobx observable has changed
Is it possible to detect when an observable changes in any way?
For instance, say you have this:
@observable myObject = [{id: 1, name: 'apples'}, {id: 2, name: 'banana' }]
And later on, with some user input, the values change. How can I detect this easily?
I want to add a global "save" button, but only make it clickable if that observable has changed since the initial load.
My current solution is to add another observable myObjectChanged
that returns true/false, and wherever a component changes the data in the myObject, I also add a line that changes the myObjectChanged to true. And if the save button is clicked, it saves and changes that observable back to false.
This results in lots of extra lines of code sprinkled throughout. Is there a better/cleaner way to do it?
Solution 1:[1]
You could use autorun
to achieve this:
@observable myObject = [{id: 1, name: 'apples'}, {id: 2, name: 'banana' }]
@observable state = { dirty: false }
let firstAutorun = true;
autorun(() => {
// `JSON.stringify` will touch all properties of `myObject` so
// they are automatically observed.
const json = JSON.stringify(myObject);
if (!firstAutorun) {
state.dirty = true;
}
firstAutorun = false;
});
Solution 2:[2]
Create an action that will push to myObject and set myObjectChanged
@action add(item) {
this.myObject.push(item);
this.myObjectChanged = true;
}
Solution 3:[3]
As capvidel mentioned, you can use autorun
to track if variable changes, but to avoid adding additional variable firstAutorun
you can replace autorun
with reaction
:
@observable myObject = [{id: 1, name: 'apples'}, {id: 2, name: 'banana' }]
@observable state = { dirty: false }
reaction(
() => JSON.stringify(myObject),
() => state.dirty = true
);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | ajma |
Solution 3 | Maksim Pautsina |