0
votes

I just started learning about Mobx to implement it in my projects, and I've come across a big issue: I seem to not understand how actions work.

I've been following this nice tutorial: https://hackernoon.com/how-to-build-your-first-app-with-mobx-and-react-aea54fbb3265 (the complete code of the tutorial is located here: https://codesandbox.io/s/2z2r43k9vj?from-embed ), and it works smoothly. I've tried to do a small React App on my side, trying to do the same the tutorial mentioned, and yet it is failing. I am sure there is some small detail (since the app is pretty simple) that I am not seeing, so I would appreciate some help on it.

I've also tried to look for similar cases to mine, but I didn't find anything through a quick search (which makes me think even more the problem is insignificant...)

My code is this:

import React, { Component } from 'react';
import { decorate, observable, action, configure } from 'mobx';
import { observer } from 'mobx-react';

configure({ enforceActions: 'always' });

class Store {
    my_number = 1;

    addNumber() {
        this.my_number += 1;
    }

    removeNumber() {
        this.my_number -= 1;
    }
}

decorate(Store, {
    my_number: observable,
    addNumber: action,
    removeNumber: action
})

const my_store = new Store();

const Button = (props) => {
    if (props.store.my_number === 1) {
        return (
            <div>
                <button onClick={props.store.addNumber}>+</button>
            </div>
        )
    } else if (props.store.my_number === 4) {
        return (
            <div>
                <button onClick={props.store.removeNumber}>-</button>
            </div>
        )
    } else {
        return (
            <div>
                <button onClick={props.store.addNumber}>+</button>
                <button onClick={props.store.removeNumber}>-</button>
            </div>
        )
    }
}

const ObserverButton = observer(Button);

const DisplayNumber = (props) => {
    return (
        <h1>My number is: {props.store.my_number}</h1>
    )
}

const ObserverDisplayNumber = observer(DisplayNumber);

export class SimpleMobxStore extends Component {
    render() {
        return (
            <div>
                <ObserverButton store={my_store} />
                <ObserverDisplayNumber store={my_store} />
            </div>
        )
    }
}

And my thoughts for developing it have been (I would also appreciate suggestions on how to improve my thoughts-flow if it's bad):

I want a text on the screen that shows a number between 1 and 4. Above this text I want to have a button that allows me to increase or decrease this number by adding or substracting a unit each time. I want this variable (the current number) to be stored in a separate store. That store will include:

  • My number
  • A method for increasing the number
  • A method for decreasing the number

In addition I will create two components: a button component that renders my button depending on the current number, and a display component.

My observable will be the number in the store, whereas the two methods will have to be decorated as actions, since they are changing the observed variable.

My button and display components will be observers, since they must be re-rendered once the number changes.

With this simple reasoning and code I was expecting it to function, but instead I'm getting a:

Error: [mobx] Since strict-mode is enabled, changing observed observable values outside actions is not allowed. Please wrap the code in an action if this change is intended. Tried to modify: [email protected]_number

The log seems to be pointing to when I define const my_store = new Store();, but this is done in the tutorial and it works there.

Any idea on where this is failing and why?

Thank you

1

1 Answers

0
votes

I think your action to the store is directly from render(). The tag to be precise. Try having a method outside the render and try changing the store state from there.