@k-ramel/react

React bindings for k-ramel

Stats

StarsIssuesVersionUpdatedCreatedSize
@k-ramel/react
20393.0.12 years ago4 years agoMinified + gzip package size for @k-ramel/react in KB

Readme

@k-ramel/react

React bindings for k-ramel

Examples & API

provide the store to react context

import { provider } from '@k-ramel/react'
import store from './store' // see k-ramel documentation about building your store

const App = () => <div>My application</div>

export default provider(store)(App)

map store to your components

component.container.js

import { inject } from '@k-ramel/react'
import Component from './component' // your react component

/* in this example we expect that the store is build with:
  createStore({
    data: {
      users: types.keyValue(),
    },
  })
*/
// this function allow you to access:
// - the whole store
// - the props given by the parent component
// - the drivers (see driver documentation if you don't know what it is)
const mapStore = (store, ownProps, drivers) => {
  // you should return an object
  // this object represent the new props to be merged with `ownProps` from parent
  // note that props written here will override parent ones
  return {
    // data
    ...store.data.users.get(ownProps.id),
    // callback that use a driver
    // - callback are not tested upon `shouldComponentUpdate` optimisation
    onRemove: () => {
      drivers.http('USERS').delete(`/api/users/${ownProps.id}`)
    },
    // The example above would be better this way
    onRemoveBetter: () => store.dispatch({ type: '@@ui/USERS>REMOVED>CLICKED', payload: ownProps.id })
    // - then plug a reation to call the http driver
    // - this way your UI and your data management are decoupled
  },
}

export default inject(mapStore)(Component)

write some logical code binded to a component

To understand this part you should first read the listeners' documentation.

First, write your reactions:
component.reactions.js

export const callDeleteUser = (action, store, drivers) => {
  drivers.http('USERS').delete(`/api/users/${action.payload}`)
}

export const removeUser = (action, store) => {
  // here we will remove user from store AFTER the API respond
  // but you can do it in parallel (by writing this line into `callDeleteUser` for example)
  store.users.remove(action.payload.id)
}

Second, write your listeners:
component.listeners.js

// import listener engine
import { when } from 'k-ramel'
// import your reactions (logical code)
import { callDeleteuser, removeUser } from './component.reactions'


// react connector needs an array of listeners
export default [
  // here you can see our UI and your logical code are decupled
  // the `@@ui/USERS>REMOVED>CLICKED` is dispatched from your component (mapStore)
  when('@@ui/USERS>REMOVED>CLICKED')(callDeleteUser),
  // when the http driver has a response, it triggers a `ENDED` event
  // you can see the full http driver to see the list of events
  // note that data is already parsed from JSON
  when('@@http/USERS>DELETE>ENDED')(removeUser),
]

Finally, you can attach your listeners to a given component.
One of the strategy is to attach listeners to a Screen of your application.
That means that your business code is attach to a particular screen:
component.container.js

// this is the previous component.container we call but we add some lines on it
// to plug ours listeners (and reactions)
// - first modification is here, we import `listen` to plug our listeners
import { inject, listen /* HERE 👋 */ } from '@k-ramel/react'
import Component from './component'
// we also import our listeners 👋
import listeners from './component.listeners'

const mapStore = (store, ownProps, drivers) => {
  return {
    ...store.data.users.get(ownProps.id),
    onRemoveBetter: () => store.dispatch({ type: '@@ui/USERS>REMOVED>CLICKED', payload: ownProps.id })
  },
}

// we use `listen` as an HoC 👋
export default listen(
  listeners,  // [REQUIRED] we pass our listeners writen above 👋
  'users', // [OPTIONAL] you can pass a name to your listeners
)(inject(mapStore)(Component))

From here, each time your component will be mounted:

  • an action will be dispatched: @@krml/LISTENERS>ADDED>users (users is the name we give just above)
  • the listeners are attached to the k-ramel store

Each time your component will be unmounted:

  • an action will be dispatched: @@krml/LISTENERS>REMOVING>users (users is the name we give just above)
  • the listeners will be removed from k-ramel store

Note that you can listen to @@krml/LISTENERS>ADDED>users in your plugued listeners since this action is dispatched AFTER listeners are added.
It means you can some screen initialisation for example.

Also note that you can listen to @@krml/LISTENERS>REMOVING>users but you CAN'T trust it to reset your store because, by React nature, ADDED action from an other screen would be dispatched BEFORE the REMOVING one.

If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.