restful-redux
tl;dr
If Redux feels like it's missing first class XHR handling, give restful-redux
a try.
More Details
GraphQL has it's place but many applications use REST-based service APIs for a variety of reasons.
There are always commonalities between action creators, reducers and smart components with redux like
- action creators have to supply the action type that the associated reducers will be scanning for
- reducers have to save state where data consuming smart components will be looking
Goals of this project
- Simplify and DRY up REST document/model oriented XHR action creation
- Simplify and DRY up associated reducers
- Provide a React component wrapper that will auto-fetch your document/model data
- Support collections
- Support additional model metadata (which can be set if the document/model has not yet been retrieved)
- Support normalizr
Installation
npm install --save restful-redux redux-effects redux-effects-fetch redux-multi redux-thunk
And apply the middleware dependencies
import effects from 'redux-effects'; // encapsulate side effects into middleware (like XHR activity)
import fetch from 'redux-effects-fetch'; // XHR middleware handler for redux-effects
import multi from 'redux-multi'; // allow arrays of actions to be dispatched
import thunk from 'redux-thunk'; // allow async callback functions to be dispatched
// when creating the redux store
applyMiddleware(multi, thunk, effects, fetch);
Basic Example
This is all you need to fetch, reduce and get access to your model data and loading states. Here we will be fetching user data.
user action creator
;const userActionCreator = ;// export our fetch method { return userActionCreator;}
user model reducer
;;
React component model provider
// notice how your React component can be a pure function { if model return <div>Loading...</div>; else if model // model.fetchError() actually returns the error payload: { headers, status, statusText, url, value } return <div>Fetch error...</div> else const user = modelvalue; return <div> userfirstName userlastName </div> } // now wrap up your component in a "modeProvider" to auto-fetch the model data;;
That's it! The modelProvider
is expected to be wrapped in a smart component
with an entities
prop available which represents the same state available to your reducer.
Docs
- Troubleshooting / FAQ
- Action Creator
- Model Provider React component
- Model Class
- Model Reducer
- Unit Testing (creating models which simulate different states)
- Advanced Collection Handling (Keeping track of item level XHR status for individual collection items)
Examples
- simple profile viewer using github API (demonstrating XHR auto-fetch and loading state indication)
- simple github project search using github API (demonstrating collections)
- previous example with paging using custom model class
- previous example with normalized entities using normalizr and helpful debug settings
- previous example with additional project details page (demonstrating no additional XHR fetch for details page because of normalized entities)