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:
- install mobx
- create store
- 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.