redux-supermodel
Streamline the effort it takes for you to communicate between your Redux Store and a REST-like API. This is a package of action creator functions and reducers built with axios and redux-promise-middleware that handle the resource state management for you... all you need is a URL!
Creating the Client
Clients encapsulate the API you are consuming. You can create a new client by providing the base URL for the API.
import { createClient } from 'redux-supermodel'
const client = createClient('https://example.com/api/v1')
Creating Resources
Within your client, you can start defining resources. Each Resource represents an endpoint that you can interact with.
const blogs = client('blogs')
const comments = client('comments')
Attaching your Resource's props to your Component
Start with your resource definition, let's pretend http://example.com/api/posts/latest
will return a JSON object with properties title
and body
.
import { createClient } from 'redux-supermodel'
const client = createClient('http://example.com/api')
export const post = client('post', { url: 'posts/latest' })
The easiest way to use redux-supermodel is with the bindResource higher-order component which will automatically fetch the resource when the component mounts, reset it when the component unmounts, and binds the resource's props and action creators to the component's props.
import React from 'react'
import { bindResource } from 'redux-supermodel'
import { post } from './resources'
function MyComponent ({ready, error, title, body, fetchPost}) {
if (!ready) return <div className="loading">Loading...</div>
if (error) return <div className="error">{error}</div>
return (
<div>
<h1>{title}</h1>
<div className="body">
{body}
</div>
<button type="button" onClick={() => fetchPost()}>Refresh</button>
</div>
)
}
export function mergeProps (stateProps, dispatchProps, ownProps) {
const {
ready,
error,
payload
} = stateProps.post
const err = error && error.response && error.response.data
const data = payload && payload.data
return {
...ownProps,
...dispatchProps,
ready,
error: err && err.message,
title: data && data.title,
body: data && data.body
}
}
const resources = { post }
export default bindResource(resources, { mergeProps })(MyComponent)
The advice offered by this blog post is about mapStateToProps, but it applies to how we are using mergeProps here.
For details on mergeProps, read the react-redux connect() documentation.
For the full list of options, see bindResource.
Installation
npm install --save redux-supermodel redux-promise-middleware
You will need to add the redux-promise-middleware
middleware and the redux-supermodel
reducer to your Redux Store.
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'
import promiseMiddleware from 'redux-promise-middleware'
import { reducer as resource } from 'redux-supermodel'
const rootReducer = combineReducers({ resource })
export default compose(applyMiddleware(promiseMiddleware()))(createStore)(rootReducer)