MobX - Reset all store observables back to initial state?

13,331

Solution 1

EDIT: this is an old answer that doesn’t work in newer versions of mobx.

If you use the reset() to initialize the object, you could avoid duplication of code. Here is what I mean:

import { extendObservable } from "mobx";

class MyQuestionStore {
  constructor() {
    this.reset();
  }

  @action reset() {
    extendObservable(this, {
      asked: 'today',
      answered: false,
      question: {
        upvotes: 0,
        body: null,
        asker: null,
        askerPoints: null,
        askerBadges: null
      }
    });
  }
}

Solution 2

I ended up having to repeat the default observables in the reset function, so it looks like this:

class MyQuestionStore {
  @observable asked = 'today';
  @observable answered = false;
  @observable question = {
    upvotes: 0,
    body: null,
    asker: null,
    askerPoints: null,
    askerBadges: null
  }

  @action reset = () => {
    this.asked = 'today';
    this.answered = false;
    this.question = {
      upvotes: 0,
      body: null,
      asker: null,
      askerPoints: null,
      askerBadges: null
    }
  }
}

const myQuestionStore = new MyQuestionStore();
export default myQuestionStore;

I still feel there is a better way than to repeat it and keep it DRY. I will keep the question open for now, hoping there is a better DRY answer.

Solution 3

If you don't need to reset deeply, the createViewModel utility from mobx-utils might come in handy: https://github.com/mobxjs/mobx-utils/#createviewmodel

Solution 4

To reset store you can do something like this:

const initialValue = {
  name: 'John Doe',
  age: 19,
}

@action reset() {
  Object.keys(initialState).forEach(key => this[key] = initialState[key]);
}

And you can set initial store values:

class myStore {
  constructor() {
    extendObservable(this, initialState);
  }
}
Share:
13,331
Wonka
Author by

Wonka

Updated on June 15, 2022

Comments

  • Wonka
    Wonka almost 2 years

    Given a MyQuestionStore store:

    class MyQuestionStore {
      @observable asked = 'today';
      @observable answered = false;
      @observable question = {
        upvotes: 0,
        body: null,
        asker: null,
        askerPoints: null,
        askerBadges: null
      }
      // some more initial state observables...
      // some actions below...
    }
    
    const myQuestionStore = new MyQuestionStore();
    export default myQuestionStore;
    

    What would be the correct way to reset all store observables back to their initial states data ('today'/false/0/null/etc..)?

    NOTE: Something like MyQuestionStore.reset() for example I think would be a good MobX way, but I don't think it exists. I would have to write an action called reset and manually reset each observable back to its initial state. I don't think that would be the right way, since if I add more observables, I would have to manually add them to the reset action every time.

  • Wonka
    Wonka over 7 years
    Hmmm... Yeah I think I am trying to reset deeply regardless of the number of times the observable was changed, sort of back to the base line default.
  • Wonka
    Wonka over 7 years
    Works very well, thank you! One minor edit is semicolons should be commas (SO won't allow me to just change them on an answer unless I change 6 characters, which I don't need to do) :)
  • mweststrate
    mweststrate over 7 years
    I heard that combination of mobx's toJS and lodash deepMerge worked well for others
  • Wonka
    Wonka over 7 years
    hmmm.. didn't know that as I've never used deepMerge from lodash. Thanks for sharing and for the awesome mobx!
  • Dygerati
    Dygerati almost 6 years
    extendObservable() doesn't reset existing observables, so it sounds like running reset() outside of the constructor wouldn't actually have the desired effect. So, in short, this doesn't work.
  • Mouad Debbar
    Mouad Debbar almost 6 years
    @Dygerati I'm quite confident this snippet was working in older versions of mobx. I'm not up-to-date with the latest changes in mobx, would you mind adding a snippet that would work for the recent versions of mobx?
  • Dygerati
    Dygerati almost 6 years
    @MouadDebbar Understood, that makes sense. I'm actually not aware of a working method to do this so far, but I'll report back if I come up with anything.