Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whats the difference between @observable and @observable.ref modifiers in mobx?

Mobx supports both @observable and @observable.ref modifiers and their official doc says

observable: This is the default modifier, used by any observable. It clones and converts any (not yet observable) array, Map or plain object into it's observable counterpart upon assignment to the given property

observable.ref: Disables automatic observable conversion, just creates an observable reference instead.

I do not understand why would we need to create a observable reference for an already existing observable. How are these two different and what are their use cases ?

like image 233
freakomonk Avatar asked Nov 14 '19 06:11

freakomonk


People also ask

What does @observable do in MOBX?

It can be used to trap existing object properties and make them observable. Any JavaScript object (including class instances) can be passed into target . Typically makeObservable is used in the constructor of a class, and its first argument is this . The annotations argument maps annotations to each member.

What is observable ref?

observable. Usage: observable.ref (annotation) Like the observable annotation, but only reassignments will be tracked. The assigned values themselves won't be made observable automatically. For example, use this if you intend to store immutable data in an observable field.

What is MOBX?

MobX is a simple, scalable, boilerplate-free state management solution. It allows you to manage application state outside of any UI framework, making the code decoupled, portable and, above all, easy to test. It implements observable values, which are essentially using the publish/subscribe pattern.


1 Answers

observable.ref will only track reference changes to the object, which means that you will need to change the whole object in order to trigger the reaction. So if you, for example, have an observable array that is tracked by reference, the contents of the array will not be tracked. Also if you add items to the array that change will also not be tracked.

import { observable, reaction } from "mobx";

const test = observable(
  {
    reference: [{ id: 1 }]
  },
  {
    reference: observable.ref
  }
);

reaction(
  () => {
    return test.reference.length;
  },
  () => {
    console.log("Reaction 1: reference length changed");
  }
);
reaction(
  () => {
    return test.reference[0];
  },
  () => {
    console.log("Reaction 2: reference item changed");
  }
);

test.reference[0] = { id: 2 }; // this will not trigger the reactions
test.reference.push({ id: 3 }); // this will not trigger the reactions
test.reference.pop(); // this will not trigger the reactions

test.reference = []; // this will trigger both reactions

code sandbox example

like image 51
Ivan V. Avatar answered Oct 25 '22 10:10

Ivan V.