MobX enables you to cut out a lot of code that is used in Redux however Redux is a popular choice for state management.
Using the @observable decorator and extending data structures such as objects, arrays and classes, this defines application state the component has access to.
import { observable } from 'mobx'
class Example {
@observable test = true;
}
...
class ExampleComp {
@observable examples = []
@computed
get theExample() {
return this.examples.filter(example => example.test).length
}
}
In the example above the value for test refers to an array. The @computed decorator enables values to be derived automatically when the value is modified.
The store allows current state to be modified.
import { observable, action, computed } from 'mobx'
class ExampleStore{
@observable examples = []
@action
addExample = example => {
this.example.push(examples)
}
@computed
get examples() {
return this.examples.length
}
}
Actions allow you to change the state. Also note, stores are injected into components.
import React, { Component } from 'react'
import { inject, observer } from 'mobx-react'
@inject('ExampleStore')
@observer
export default class extends Component {
render() {
return (
<>
<p>{this.props.ExampleStore.examples}
</>
)
}
}
The state of the application lives inside the store. The store contains the main rootReducer. Within the reducer folder you are likely to have many reducers that are all pulled through the rootReducer file, as shown below.
import { combineReducers } from 'redux'
import dataReducer from './dataReducer'
export default combineReducers({
dataReducer
})
Redux uses pure functions, this means itβs difficult to manipulate data with functionality such as API requests. To get around this you can use a middleware. In Redux you have two options redux-saga and redux-thunk.
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import rootReducer from './reducers/'
export default function configureStore() {
return createStore(rootReducer, applyMiddleware(thunk))
}
The state returns from the reducers. In Redux state cannot be changed unlike within a component which can be changed with setState. The reducer is a function which takes in the state and action.
export default(state = {}, action => {
switch(action.type) {
case 'THE_TEST':
return {
...state,
test: action.payload
}
default:
return state
}
})
Actions are objects which enable the the reducer to understand when to set the next state; through a signal to the store via an action, usually known as dispatching an action.
import { THE_TEST } from './types'
export const theTest = (payload) => {
return {
type: THE_TEST,
payload
}
}
export const getTest = () => {
return function(dispatch) {
dispatch(theTest())
}
}
//types file
export const THE_TEST = 'THE_TEST'
When setting up Redux, ensure there is a store, reducers and actions. In MobX the store will be very similar.
Create all reducers you will need for your application. Usually this will be in the form of observables.
Create a types files for all actions and create actions for all corresponding reducers
Ensure the store has a middleware