6.1.1 • Published 7 years ago

mobx-actions v6.1.1

Weekly downloads
18
License
MIT
Repository
github
Last release
7 years ago

Mobx-Actions

a reinvisioning of Mobx @actions. Requires Mobx@3|4

Dispatch arguments (actions) from anywhere, and respond to them on your stores with actionHandlers.

Example

import * as React from 'react'
import MobxActions from 'mobx-actions'
import { useStrict, observable, computed } from 'mobx'
import { observer } from 'mobx-react'
useStrict(true)
import { render } from 'react-dom'

const actionTypes = [
    'IncrementedCount',
    'DecrementedCount'
]

const { actions, subscriber } = MobxActions(actionTypes)

@subscriber
class CounterStore {
    @observable count = 0
    actionHandlers = {
        IncrementedCount: ({ amount }) => {
            this.count += amount
        },
        DecrementedCount: ({ amount }) => {
            this.count -= amount
        }
    }
}
const counterStore = new CounterStore()

@subscriber
class CommentaryStore {
    @observable news = `Nothing's happened yet`
    @computed get analysis() {
        const { count } = counterStore
        const oddOrEven = count % 2 ? 'odd' : 'even'
        return `The current count is ${oddOrEven}.`
    }
    actionHandlers = {
        IncrementedCount: () => {
            this.news = 'The count was incremented.'
        },
        DecrementedCount: () => {
            this.news = 'The count was decremented.'
        }
    }
}
const commentaryStore = new CommentaryStore()

const Counter = observer(() => {
    const { count } = counterStore
    const { news, analysis } = commentaryStore
    
    return <div>
        <div>{news}</div>
        <div>{analysis}</div>
        <button onClick={() => {
            actions.DecrementedCount({ amount: 1 })
        }}>-</button>
        <span>{count}</span>
        <button onClick={() => {
            actions.IncrementedCount({ amount: 1 })
        }}>+</button>
    </div>
})

render(<Counter />, document.getElementById('root'))

Advantages

Mobx-Actions prevents imperative code from touching multiple stores.

Stores update themselves independently in response to events, which cleanly separates concerns.

// instead of this...
<button onClick={e => {
    RegistrationStore.submitRegistration()
    NavigationStore.navigateToRegistrationConfirmation()
}}>
    Register
</button>

//...try this
<button onClick={e => {
    actions.ClickedRegisterButton()
}}>
    Register
</button>
//...and define a `ClickedRegisterButton` handler
// on the two relevant stores

Restrictions

  • Actions dispatched must be a single argument. Other arguments will be ignored.
  • An action handler must be mapped in a @subscriber's actionHandler property to be invoked.

Middleware

If you would like to modify the behavior of Mobx-Actions, you can do so thorugh middleware.

const repeatingMiddleware = (ctx, next) => {
    const {
        dispatchId,
        actionType,
        action,
        store,
        handler
    } = ctx
    
    next()
    
    // the equivalent of calling `next()` again
    handler(action)
}

const { actions, subscriber } = 
    MobxActions(actionTypes, repeatingMiddleware)

Most users will not require middleware. But if you do, it is extremely flexible.

Other examples

If you want to see a larger example, check out this boilerplate.

6.1.1

7 years ago

6.1.0

7 years ago

6.0.0

7 years ago

5.0.2

7 years ago

5.0.1

7 years ago

5.0.0

7 years ago

4.1.0

7 years ago

4.0.2

7 years ago

4.0.1

7 years ago

4.0.0

7 years ago

3.0.0

7 years ago

2.0.2

7 years ago

2.0.1

7 years ago

2.0.0

7 years ago

1.0.0

7 years ago