Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 836
capvidel Avatar asked Oct 11 '16 22:10

capvidel


People also ask

Is MobX deprecated?

https://github.com/mobxjs/mobx/ is now monorepo with all the packages, so nothing is deprecated.

Is MobX better than redux?

Debug process: Compared to MobX, debugging in Redux is a better experience because it has more developer tools and less abstraction. The Redux becomes more predictable with the flux paradigm. Debugging in MobX is much more difficult due to increased abstraction and average developer tools.

How does MobX Autorun work?

Autorun works by running the effect in a reactive context. During the execution of the provided function, MobX keeps track of all observable and computed values that are directly or indirectly read by the effect.

How does MobX observer work?

The observer HoC automatically subscribes React components to any observables that are used during rendering. As a result, components will automatically re-render when relevant observables change. It also makes sure that components don't re-render when there are no relevant changes.


1 Answers

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;
});
like image 155
Mouad Debbar Avatar answered Sep 22 '22 17:09

Mouad Debbar