Abdullah Monoar
Abdullah Monoar

Reputation: 31

Mobx autorun based on computed value being true

I'm still fairly new to MobX, I understand the concepts of computed, autorun, observables. But I'm struggling with a certain scenario. I have the following code in my store (I'm using mobx-state-tree) :

export const store = types
    .model({
        renderingState: types.optional(types.string, 'stage1'),
        containerMounted: types.optional(types.boolean, false),
    })
    .views(self => ({
        //computed value
        isReady() {
            if (self.renderingState === 'stage3' && self.containerMounted) {
                return true;
            }
        }
    }))

Now essentially, I want to run a function loadConfigurations when the computed value is true. In this scenario I want to run my function when renderingState is stage3 and containerMounted is true. From my understanding of autorun, it will fire as soon as the computed value changes. But I would like my function to fire when the if statement is valid.

If you have any insight or could help clarify any misconception I have that would be great.

Upvotes: 2

Views: 893

Answers (1)

etudor
etudor

Reputation: 1200

The first issue is that your isReady property is not computed. To make it a computed it should be like this

    .views(self => ({
        //computed value
        get isReady(): boolean {
            if (self.renderingState === 'stage3' && self.containerMounted) {
                return true;
            }

            // add the default value
            return false;
        }
    }))

Now that the isReady is a computed property you can simply use it inside autorun

autorun(() => {
    if (myStore.isReady) {
        // your logic goes inside the if
        console.log("My store is ready")
    }
})

OR

autorun(() => {
    if (!myStore.isReady) {
        return false
    }

    // your logic goes here
})

The function inside autorun will run every time isReady changes it's value, true/false When it goes from false to true the logic will get executed.

TBH I don't really use autorun, I like to use reaction inside the afterCreate method like this

export const store = types
    .model({
        renderingState: types.optional(types.string, 'stage1'),
        containerMounted: types.optional(types.boolean, false),
    })
    .actions(self => ({
      afterCreate() {
        addDisposer(self, reaction(
          () => {
            return self.isReady
          },
          () => {
            if (self.isReady) {
              // your logic should go here
            }
          }
        ))  
      }
    }))
    .views(self => ({
        //computed value
        get isReady() {
            if (self.renderingState === 'stage3' && self.containerMounted) {
                return true;
            }

            return false;
        }
    }))

Upvotes: 3

Related Questions