Add mobx to your React project

Mobx helps you manage the state.

I set up mobx to be used as an import to your (functional) components. I do this, rather than using createContext() because the latter one only allows you to use it inside components, not functions.

To set up mobx you’ll need to:

  1. install mobx
  2. create store
  3. configure store and components

In this example, I make use of the function autoStore() in the constructor of the store to save the state to localStorage whenever there is a change to the state.
This makes that state is saved across page-refreshes.

install mobx

Install with:

yarn add mobx mobx-react

create store

Create your store by creating file src/stores/uiStore.tsx.

This will be one of the stores you can use. You can create as many stores as you want.

// file src/stores/uiStore.tsx
import {makeAutoObservable} from "mobx";

const uiStore = () => makeAutoObservable({
    showLocations: false as boolean,
    toggleShowLocations(){
        this.showLocations = ! this.showLocations
    },
})

export default uiStore

Next, we add this store to the context. This makes that we can access all stores via the useStore context.

// file ./src/stores/index.tsx
import {createContext, useContext} from "react";
import uiStore from "./uiStore";

const store = {
    ui: uiStore(),
}

export const StoreContext = createContext(store)

export const useStore = () => {
    return useContext<typeof store>(StoreContext)
}

export default store

In your App.tsx, add the StoreContext so every child component can make use of it.

// file ./src/App.tsx
...
import store, {StoreContext} from "../stores";
...

const MyApp = () => {
    ...

    return (
      <StoreContext.Provider value={store}>
            <Header />
            <Switch>
                  ...
            </Switch>
      </StoreContext.Provider>
    )
}

File ./src/libs/autoStore.js takes care of storing the state in localStorage.

// file ./src/libs/autoStore.tsx
import { toJS, autorun, set } from 'mobx'

export default function (_this: any, storeName='store') {
    let firstRun = true

    // will run on change
    autorun(() => {
        // on load check if there's an existing store on
        // localStorage and extend the store
        if (firstRun) {
            const existingStore = window.localStorage.getItem(storeName)

            if (existingStore) {
                set(_this, JSON.parse(existingStore))
            }
        }

        // from then on serialize and save to localStorage
        const serializedThis = toJS(_this)
        window.localStorage.setItem(
            storeName,
            JSON.stringify(serializedThis)
        )
    })

    firstRun = false
}

Use the store: configure store and components

Configure your components by wrapping them with the observer() function of mobx.

By doing this, mobx knows whenever something changes that concerns the state.

// file ./src/components/SayHello.js

import React, { Component } from 'react'
import { observer } from 'mobx-react-lite'
import {useStore} from "../../stores";

const SayHello = () => {
   const {ui} = useStore()

   return <div>{ui.showLocations && 'Hi locations!'}</div>
}

export default observer(SayHello)

Resources

Take a look at these pages. They provide useful information about working with mobx.

Click Here to Leave a Comment Below

Leave a Reply: