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