Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I clone a MobX observable? (edit save changes)

Tags:

reactjs

mobx

I have a simple react form, and two observables in my MobX store:

@observable personalInfo = {
        email: '',
        gender: 1,
        birthDate: null, 
        location: ''
    };
@observable personalInfoInEdit = null;

When the form of the personal info is loaded (in the ctor) I am calling a method on my store:

reset_PersonalInfoInEdit() {
        this.personalInfoInEdit = observable(this.personalInfo);
}

What it dose is simply reseting the "in edit" object, filling it with data from the original data. If the user press "save changes" the "in edit" object will be copied to the original.

Is calling observable() with another observable is valid? Any side effects to this? (it seems to work)

And if not, are there are design patterns to elegantly handle this scenario of "in edit" object.

like image 678
Yaron Levi Avatar asked Oct 21 '16 21:10

Yaron Levi


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 .

What is toJS in MobX?

toJS. Usage: toJS(value) Recursively converts an observable object to a JavaScript object. Supports observable arrays, objects, Maps and primitives. It does NOT recurse into non-observables, these are left as they are, even if they contain observables.

What is inject in MobX react?

The store injection pattern was popularized by the mobx-react library. It refers to a now obsolete way of accessing the MobX stores across the component tree. It was introduced because the React legacy context was rather awkward to use.

How do I use react in MobX?

Below is a simple example. import React from "react"; import ReactDOM from "react-dom"; import { makeAutoObservable } from "mobx"; import { observer } from "mobx-react"; // Model the application state. class Timer { secondsPassed = 0; constructor() { makeAutoObservable(this); } increase() { this.


1 Answers

The preferred pattern would be to use createViewModel utility function from mobx-utils. So you would do:

import { createViewModel } from 'mobx-utils'

reset_PersonalInfoInEdit() {
    this.personalInfoInEdit = createViewModel(this.personalInfo);
}

this has an added benefit of having some utility functions on the view model that allow you easily to reset to original data or submit them to original model:

class Todo {
  \@observable title = "Test"
}

const model = new Todo()
const viewModel = createViewModel(model);

autorun(() => console.log(viewModel.model.title, ",", viewModel.title))
// prints "Test, Test"
model.title = "Get coffee"
// prints "Get coffee, Get coffee", viewModel just proxies to model
viewModel.title = "Get tea"
// prints "Get coffee, Get tea", viewModel's title is now dirty, and the local value will be printed
viewModel.submit()
// prints "Get tea, Get tea", changes submitted from the viewModel to the model, viewModel is proxying again
viewModel.title = "Get cookie"
// prints "Get tea, Get cookie" // viewModel has diverged again
viewModel.reset()
// prints "Get tea, Get tea", changes of the viewModel have been abandoned
like image 174
Tomas Holas Avatar answered Oct 08 '22 11:10

Tomas Holas