🚧 🚧 RIGHT NOW THIS MIDDLEWARE DOESN'T WORK WITH AN UGLIFY VERSION OF YOUR MOBX-STATE-TREE STORE, LOOK A THIS MOBX_STATE_TREE ISSUE FOR MORE INFORMATIONS: Issue #492 🚧 🚧
Listen to mobx-state-tree actions and react to them !
Make your mobx-state-tree store a real tree, not a graph
The main purpose is to get rid of store interdependencies and to be more into a reactive way of coding.
What we want is to pass from an actions dependencies graph to a tree:
yarn add k-mst-onaction
npm i k-mst-onaction
- Import the middleware from k-mst-onaction:
import onAction from 'k-mst-onaction'
- Write your reaction, the easiest way is to write it as a function:
const dispatch = (action, tree) => {
const { fullpath, ended } = action
if (fullpath === '/auth/login' && ended) {
tree.ui.router.goToList()
}
}
- Connect the middleware to your root store with
addMiddleware
from mobx-state-tree:addMiddleware(yourStore, onAction(dispatch))
- Voila !
As you see on the First try what you have to do is to give a dispatch
function to the onAction
middleware.
The dispatch
function can be of two different types:
- an array, in this case, each function of the array will be called
- a function, in this case the function will be called
- if the
dispatch
function returns an array, then the middleware will iterate over the array and call each functions that compose it
- if the
You can use the take
helper to avoid dealing with the API and have a cleaner code.
From First try example code with take
helper:
import { addMiddleware } from 'mobx-state-tree'
import onAction from 'k-mst-onaction'
import Store from './your-store-model'
// instanciate the store
const store = Store.create({})
// the actions to trigger
const dispatch = (action, tree) => [
take.ended('/auth/login', () => { tree.ui.router.goToList() })
]
// attach the onAction middleware from k-mst-onaction
addMiddleware(store, onAction(dispatch))
Note that:
- dispatch returns an array
- we call
take.ended
which will test that the asynchronous action is ended - we pass the full action name (path + name) as first parameter
- we pass the reaction as second one parameter
take
is an helper that takes two arguments (take(test, reaction)
):
- first argument is the
test
, it can be- a string: this string will be converted to a regular expression then the match is tested with fullpath
'/user/add'
will work against'/user/add/'
'/user/:id/setName'
will work against'/user/12/setName'
- a regular expression: then the fullpath is tested over the regular expression
- a function: the function is called and should return true to have the reaction called
- the function takes two arguments: the
action
to test and the currenttree
(your store instance)
- the function takes two arguments: the
- a string: this string will be converted to a regular expression then the match is tested with fullpath
- second argument is the
reaction
, this is a function with two parameters (reaction(action, tree)
):action
is the action that pass the test (first argument oftake
)tree
is your current store instance, so you can call action on it !
As you can see, the action
object is given to your dispatch
function, and to first and second parameters of take
helper.
This action
owns these fields:
- path: the action path from the root store
- name: the action name
- fullpath:
path + '/' + name
- ended: for asynchronous action only, it means the aynchronous action is ended
We will write 4 ways of doing a router redirection after our login is successful:
dispatch
is a function (that doesn't return an array)dispatch
is a function that returns an array- with a not pure
take
helper function use - with a pure
take
helper function use
- with a not pure
dispatch
is an array
import { addMiddleware } from 'mobx-state-tree'
import onAction from 'k-mst-onaction'
import Store from './your-store-model'
const store = Store.create({})
const dispatch = (action, tree) => {
const { fullpath, ended } = action
if (ended && fullpath === '/auth/login') {
tree.ui.router.goToList()
}
}
addMiddleware(store, onAction(dispatch))
import { addMiddleware } from 'mobx-state-tree'
import onAction, { take } from 'k-mst-onaction'
import Store from './your-store-model'
const store = Store.create({})
const dispatch = (action, tree) => [
take.ended('/auth/login', () => { tree.ui.router.goToList() }),
]
addMiddleware(store, onAction(dispatch))
import { addMiddleware } from 'mobx-state-tree'
import onAction, { take } from 'k-mst-onaction'
import Store from './your-store-model'
const store = Store.create({})
const dispatch = () => [
take.ended('/auth/login', (action, tree) => { tree.ui.router.goToList() }),
]
addMiddleware(store, onAction(dispatch))
❤️ This is the recommended way of using this middleware ❤️
import { addMiddleware } from 'mobx-state-tree'
import onAction, { take } from 'k-mst-onaction'
import Store from './your-store-model'
const store = Store.create({})
const dispatch = [
take.ended('/auth/login', (action, tree) => { tree.ui.router.goToList() }),
]
addMiddleware(store, onAction(dispatch))
uni rakun is created by two passionate french developers.
Do you want to contact them ? Go to their website
Guillaume CRESPEL | Fabien JUIF |