npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@k-ramel/react

v3.0.1

Published

React bindings for k-ramel

Downloads

235

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.