Redux Resources
An opinionated, yet extendable, set of redux action creators and reducers that simplify creating, reading, updating, and deleting remote resources. Redux Resources takes the boilerplate out of managing your api cache.
The Gist
Redux Resources gives you a set of functions, (retrieveResource
, listResource
, createResource
, updateResource
, partialUpdateResource
, deleteResource
), that return action creators and their respective action type constants that can be used to interact with remote resources. These methods accept a configuration object that lets you define the name of the resource and how it should be interacted with (how to fetch, normalize, what to do with errors, etc).
All action creators use redux-thunk to trigger one to many actions, based on your state tree. In general, an initial action will be triggered to set your state tree to "isFetching" and a following action will be triggered that adds any changes to the targeted resources. Errors will also trigger an action to remove the isFetching state and add any formatted Errors to that resources state.
Before getting started, make sure you have redux-thunk added in your redux middleware:
const middleware = thunkconst store =
Then, in your root reducer file add:
const rootReducer =
In your actions file, call retrieveResource with some config to get back the retrieveExampleResource
action creator and it's action type constants:
const RETRIEVE_EXAMPLE_RESOURCE_REQUEST RETRIEVE_EXAMPLE_RESOURCE_REQUEST_SUCCESS RETRIEVE_EXAMPLE_RESOURCE_REQUEST_ERROR retrieveExampleResource } =
Now, call retrieveExampleResource
with an ID
and after the request has complete, your state tree will look like:
//your existing state... resources: exampleResource: selectedResource: 'aResourceId' selectedResourceList: null resources: 'aResourceId': /* whatever was returned by the API */ resourceLists: {} resourcesBeingFetched: resourceListsBeingFetched: errors: isFetching: false lastListedAt: null lastRetrievedAt: '2016-10-16T22:51:48.473Z' lastDeletedAt: null lastCreatedAt: null lastUpdatedAt: null
To use that returned resource, use one of the included selectors:
const SomeComponent = //render JSX const mapStateToProps = exampleResource: mapStateToPropsSomeComponent
Installation
To install:
npm install --save redux-resources
This library uses a set of peer dependencies that have been widely adopted by the redux community:
API Reference
Note: You can see snapshot examples of actions triggered by redux resource generated action creators and the resulting reducer states.
Action Functions
All redux-resources action functions accept a single config object as it's only param. The response will always be an action creator with the camelCased name, "action type" + "capitalized resource". Action type constants follow a similar uppercased naming schema:
//some examples of the returned action creator/constants const RETRIEVE_FOOBAR_REQUEST RETRIEVE_FOOBAR_REQUEST_SUCCESS RETRIEVE_FOOBAR_REQUEST_ERROR retrieveFoobar } = const UPDATE_SOME_WEIRD_NAME_REQUEST UPDATE_SOME_WEIRD_NAME_REQUEST_SUCCESS UPDATE_SOME_WEIRD_NAME_REQUEST_ERROR updateSomeWeirdName } =
There are also a set of common config properties that must be passed to all of Redux Resource's action functions:
createResource(configObject)
Returns an action creator used to create a new resource:
const CREATE_EXAMPLE_RESOURCE_REQUEST CREATE_EXAMPLE_RESOURCE_REQUEST_SUCCESS CREATE_EXAMPLE_RESOURCE_REQUEST_ERROR createExampleResource } = //action creator has one param before the options object, the payload of the create resource requestconst payload = newField: 'newField' anotherNewField: 'anotherNewField'
retrieveResource(configObject)
Returns an action creator used to retrieves a single resource. This action creator will only fetch the resource if it doesn't already exist within the client cache (see isCachedFn below). If the resource does exist and is not the current selectedResource
, trigger the SELECT_RESOURCE
action:
const RETRIEVE_EXAMPLE_RESOURCE_REQUEST RETRIEVE_EXAMPLE_RESOURCE_REQUEST_SUCCESS RETRIEVE_EXAMPLE_RESOURCE_REQUEST_ERROR SELECT_EXAMPLE_RESOURCE retrieveExampleResource } = //action creator has one param before the options object, the id of the requested resource /*retrieveResource action creators also accept a shouldIgnoreCache prop that can be passed in to options.if passed, the resource will be fetched and updated even if it already exists in the redux state*/
listResource(configObject)
Returns an action creator used to retrieves a list of resources. This action creator accepts a query object as it's only param other than the options object and will only fetch the list of resources if the set matching the passed query params doesn't already exist within the client cache (see isCachedFn below). If the list does exist and is not the current selectedResourceList
, trigger the SELECT_RESOURCE
action:
const LIST_EXAMPLE_RESOURCE_REQUEST LIST_EXAMPLE_RESOURCE_REQUEST_SUCCESS LIST_EXAMPLE_RESOURCE_REQUEST_ERROR SELECT_EXAMPLE_RESOURCE_LIST listExampleResource } = const exampleQuery = limit: 30 offset: 0 status: 'active'//action creator has one param before the options object, the query of the requested list /*similar to retrieveResource, you can pass a shouldIgnoreCache prop within the options object. if passed,the list will be fetched and updated even if it already exists in the redux state*/
updateResource(configObject)
and partialUpdateResource(configObject)
Both return an action creator used to update a given resource. The difference is whether the payload includes only the updated fields or the entire new resource (PATCH vs. PUT in most RESTful APIs):
const PARTIAL_UPDATE_EXAMPLE_RESOURCE_REQUEST PARTIAL_UPDATE_EXAMPLE_RESOURCE_REQUEST_SUCCESS PARTIAL_UPDATE_EXAMPLE_RESOURCE_REQUEST_ERROR partialUpdateExampleResource } = const payload = someField: 'field being updated' /*both action creators also accept an option isOptimisticUpdate property in the options object. Whenpassed, the `PARTIAL_UPDATE_RESOURCE_REQUEST_SUCCESS` action triggers immediately with the new info andif an error is returned, `PARTIAL_UPDATE_RESOURCE_REQUEST_ERROR` will revert the changes in addition tosetting any errors*/
deleteResource(configObject)
Returns an action creator used to deletes a resource. This action creator accepts id of the resource being deleted:
const DELETE_EXAMPLE_RESOURCE_REQUEST DELETE_EXAMPLE_RESOURCE_REQUEST_SUCCESS DELETE_EXAMPLE_RESOURCE_REQUEST_ERROR deleteExampleResource } = //action creator has one param before the options object, the query of the requested list
Extending Redux Resources functionality
The library builds on top of redux but purposely plays nice with any other existing business logic you would like to add.
Reducers that you pass to resourcesReducer
must have all the fields in getResourceInitialState
, but you can layer on anything else you'd like:
const initialState = ... customReducerProperty: nullconst exampleResourceReducer = state
And just like normal redux reducers, you can respond to any dispatched redux resource action
const exampleResourceReducer = { }