0.11.0 ā€¢ Published 6 years ago

k-mst-onaction v0.11.0

Weekly downloads
1
License
MIT
Repository
github
Last release
6 years ago

k-mst-onaction

šŸš§ šŸš§ 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

CircleCI Coverage Status NPM Version Size

Contents

Purpose

The main purpose is to get rid of store interdependencies and to be more into a reactive way of coding.

Why

you can see this issue.

What we want is to pass from an actions dependencies graph to a tree:

Installation

  • yarn add k-mst-onaction
  • npm i k-mst-onaction

API

First try

  1. Import the middleware from k-mst-onaction: import onAction from 'k-mst-onaction'
  2. 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()
      }
    }
  3. Connect the middleware to your root store with addMiddleware from mobx-state-tree: addMiddleware(yourStore, onAction(dispatch))

  4. Voila !

Middleware API

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

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 API

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 current tree (your store instance)
  • 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 of take)
    • tree is your current store instance, so you can call action on it !

Action API

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

Examples

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
  • dispatch is an array

dispatch is a function (that doesn't return 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))

dispatch is a function that returns an array - impure take

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))

dispatch is a function that returns an array - pure take

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))

dispatch is an array ļøā¤ļø

ā¤ļø 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))