How to manage state?

State management in React is a very broad topic and new patterns are introduced often. MobX simplifies some things, but there's still several approaches to use (#ILikeOptions).

Creating a state

State in MobX is represented by any observable object. You can use any of the mentioned approaches in the linked document.

For advanced and more robust state, the better choice might be mobx-state-tree.

Lastly we have shiny new Hooks to help on this journey like useLocalStore(not available in class components).

  1. import { observable } from 'mobx'
  2. import { useLocalStore } from 'mobx-react' // 6.x or mobx-react-lite@1.4.0
  3. function CreatingState() {
  4. const simpleState = React.useRef(observable.array([1, 2, 3])).current
  5. const [bigState] = React.useState(createExpensiveStore)
  6. const localState = useLocalStore(() => ({
  7. count: 0,
  8. inc() {
  9. localState.count += 1
  10. },
  11. }))
  12. return <Rendering simple={simpleState} big={bigState} local={localState} />
  13. }
  14. class CreatingState extends React.PureComponent {
  15. // or use constructor if class properties are not available for you
  16. simpleState = observable.array([1, 2, 3])
  17. render() {
  18. // class component does not support any other way of
  19. // keeping observable state within a component
  20. return <Rendering simple={this.simpleState} />
  21. }
  22. }

Fair warning. Don't ever use React.useMemo to keep reference to the state object. It may be randomly thrown away by React and you may lose data.

Accessing a state

The second important aspect of state management is how to pass created observables around the component tree. There is no MobX related logic, but it's certainly worth mentioning here.

In simple scenarios, you can create an observable locally within a component and then pass it manually through props (as shown above). It's pretty much the same approach you would use with, e.g., useReducer except you will be passing a single object around only.

For a more robust state management, it's recommended to use React Context over the legacy inject.

Global variable state?

It's possible to keep application state in global variables that would get imported in component files. It will work in most cases.

However, if you are writing tests (you should), global variables are a problem and can cause flakiness. In short, we don't recommended keeping state in global variable.