Mobx’s observable loses child objects equality

Tags: ,



When I create an observable from plain object which contains fields that are effectively same objects, this property are not equal objects anymore. So if I change one’s property, the second stay untouched.

Is there a proper way to handle this?

import { observable } from "mobx";

const status = { id: "some-obj" };

const obj = {
  status,
  status2: status
};

const observableObj = observable(obj);

const isEqual = observableObj.status2 === observableObj.status;

document.body.innerHTML = `Is equal = ${isEqual}`;
console.log(observableObj);

https://codesandbox.io/s/mobx-equality-demo-5eowk

Answer

When you call observable on regular object it does not mutate it, but creates new observable object. And MobX does it recursively on every inner object or value, so that’s why observableObj.status2 and observableObj.status are not equal. They were created from same “blueprint” object, but each is independent copy, if I can say so.

Original status is still regular object, and status2 became observable object inside observableObj. Hope it makes sense.

What you can do is just make status observable by it self, before passing it inside obj, like so:

const status = observable({ id: "some-obj" });

const obj = {
  status,
  status2: status
};

const observableObj = observable(obj);

observableObj.status2 === observableObj.status // => true

That way Mobx is not going to do anything on it since it is already an observable.

Codesandbox: https://codesandbox.io/s/httpsstackoverflowcomquestions64032286-rxj5m?file=/index.js



Source: stackoverflow