1.1.0 • Published 7 years ago

cerebral-mobx v1.1.0

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

cerebral-mobx

Combine Cerebral with Mobx state-tree.

State and model

With Mobx state tree you also define models, in addition to state. You do this directly in your modules:

modules/app.js

import { types } from 'mobx-state-tree'
import {set} from 'cerebral/operators'
import {state, props} from 'cerebral/tags'

const Box = types.model('Box', {
  id: types.identifier(),
  name: '',
  x: 0,
  y: 0,
  get width() {
    return this.name.length * 15
  }
})

export default {
  model: {
    boxes: types.map(Box),
    selection: types.reference(Box)    
  },
  state: {
    boxes: {},
    selection: null
  },
  signals: {
    boxSelected: set(state`app.selection`, state`app.boxes.${props`boxKey`}`)
  }
}

Instantiate

Instead of creating the controller from cerebral, you create it from this package:

import {Controller} from 'cerebral-mobx'
import app from './modules/app'

export default Controller({
  modules: {app}
  // Other config options are the same
})

Accessing state and props in components

For example using React you will need the package mobx-react and use the provide() method of the controller:

main.js

import React from 'react'
import {render} from 'react-dom'
import controller from './controller'
import {Provider} from 'mobx-react'
import App from './components/App'

render((
  <Provider {...controller.provide()}>
    <App />
  </Provider>
))

App.js

import React from 'react'
import {observer, inject} from 'mobx-react'

@observer
@inject('store', 'signals')
class App extends React.Component {
  renderBoxes () {
    const {store, signals} = this.props

    return Object.keys(store.app.boxes).map((boxKey) => {
      return (
        <li onClick={() => signals.app.boxSelected({boxKey})}>
          {store.app.boxes[boxKey].name}
        </li>
      )
    })
  }
  render () {
    const {store} = this.props

    return (
      <div>
        <h1>{store.app.selection && store.app.selection.name}</h1>
        <ul>
          {this.renderBoxes()}
        </ul>
      </div>
    )
  }
}

export default App