@k-ramel/react
    TypeScript icon, indicating that this package has built-in type declarations

    3.0.1 • Public • Published

    @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.

    Keywords

    none

    Install

    npm i @k-ramel/react

    DownloadsWeekly Downloads

    45

    Version

    3.0.1

    License

    MIT

    Unpacked Size

    18.6 kB

    Total Files

    6

    Last publish

    Collaborators

    • fabienjuif
    • guillaumecrespel