A composable API for reusable React code.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
demo
docs
docsSrc
src
styles
test
webpack
.editorconfig
.gitignore
.npmignore
LICENSE
README.md
SUMMARY.md
book.json
circle.yml
package.json
tsconfig-build.json
tsconfig.json
tslint.json
yarn.lock

README.md

Chainable Components

A composable API for reusable React code.

Chain together reusable React components:

withState(0).chain(outer => 
  withState(outer.value + 5).map(inner =>
    ({inner, outer})
  )
).render(({inner, outer}) => (
  <div>
    <div>Outer: {outer.value} <button onClick={() => outer.update(outer.value + 1)}>+</button></div>
    <div>Inner: {inner.value} <button onClick={() => inner.update(inner.value + 1)}>+</button></div>
  </div>
));

Transform HOCs and Render Props to chainables and back:

Chainable pipeline

👇 Here's a blog post that introduces the API.
https://paulgray.net/chainable-components

Example:

import { Route } from 'react-router';
import { connect } from 'react-redux';

const withConnect = fromHigherOrderComponent(connect(mapState, mapDispatch));
const withRoute = fromRenderProp(Route);

// withConnect and withRoute are now chainable!
const withConnectAndRoute = 
  withConnect.chain(storeProps => 
    withRoute.map(route => ({
      store: storeProps,
      path: route.history.location.pathname
    })));

// then render it!
withConnectAndRoute.render(({store, path}) => (
  <div>
    current path is: {path}
    store contains: {store.users}
  </div>
));

// or convert it back render prop:
const ConnectAndRoute = withConnectAndRoute.toRenderProp();
<ConnectAndRoute>
  {({store, path}) => (
    <div>
      current path is: {path}
      store contains: {store.users}
    </div>
  )}
<ConnectAndRoute>

// or convert it back to a HOC:
const connectAndRouteHoc = withConnectAndRoute.toHigherOrderComponent(p => p);

connectAndRouteHoc(({store, path}) => (
  <div>
    current path is: {path}
    store contains: {store.users}
  </div>
));