Really simple isomorphic fetch for Redux. Can be used in any Redux project that uses (temporary) fork of redux-api-middleware.
Recommended method for simple isomorphic HTTP data fetching in Roc.
npm install --save redux-fetcher
Import
import { createFetchAction, createFetchReducer } from 'redux-fetcher';
Create your fetch actions using createFetchAction
.
Create your fetch reducers using createFetchReducer
.
The example illustrates requesting some data from the open weather map API.
const FETCH_WEATHER = 'weather';
This can be any unique string that will identify your request and its corresponding key in the state tree.
const fetchWeather = createFetchAction(
FETCH_WEATHER,
'http://api.openweathermap.org/data/2.5/forecast/daily?q=Oslo&appid=2de143494c0b295cca9337e1e96b00e0'
);
The action fetchWeather
can then be used with dispatch()
directly, or if using react-redux
through mapDispatchToProps
and used like normal in your React components.
The generated reducer will ensure that the state is updated according to the internal fetch actions.
const fetchWeatherReducer = createFetchReducer(FETCH_WEATHER);
When adding your reducer to Redux using combineReducers
, it is important that the key is equalent to the action/reducer identifier above:
const myReducers = combineReducers({
[FETCH_WEATHER]: fetchWeatherReducer
});
Done!
For the rest of this section we assume
const state = store.getState();
After a successful dispatch of fetchWeather
and it's following actions your data will be in state.weather.payload
along with state.weather.error
and state.weather.loading
. Some useful data like endpoint
is also set to state.weather.meta
. These can optionally be used to give a better user experience.
When fetchAction
is dispatched the following will happen internally:
- It will check if the
fetch
should take place at all (See options) - It dispatches an action named
WEATHER_FETCH_PENDING
- The
fetchWeatherReducer
handlesWEATHER_FETCH_PENDING
and will set thestate.weather.loading
totrue
,state.weather.error
tofalse
andstate.meta.endpoint
to the requested URL that is currently loading. - It (through
redux-api-middleware
) performs an isomorphicfetch
usingurl
. This operation is async, and what it does depends if the fetch fails or succeeds.
- It dispatches an action named
WEATHER_FETCH_SUCCESS
. The response will be stored instate.weather.payload
.state.weather.error
andstate.weather.loading
will always be false after reducing a success. Againstate.weather.meta
will provideendpoint
, but also aresponse
object with some basic information.
- It dispatches an action named
WEATHER_FETCH_FAILURE
.state.weather.payload
will contain the errorname
andmessage
.state.weather.error
will be set totrue
andstate.weather.loading
will be false after reducing an error.state.weather.meta
will provideendpoint
.state.weather.meta
will also provideresponse
if it was not a network error.
fetchAction(id, url, options)
id
: string uniquely identifying your fetch operationurl
: string containing url to fetchoptions
: object
Default:
{
force: false,
method: 'GET',
body: '',
headers: undefined,
credentials: undefined,
bailout: undefined
}
- `force`: boolean, set to true if you wish to perform fetch even if you have data in your store already. Only applies if you do not override bail yourself.
- `method`: string, HTTP method to use in fetch.
- `body`: string, request body to use (only applies to non-GET and non-HEAD requests)
- `headers`: object, specify custom HTTP headers to use in your request
- `credentials`: string, `omit`, `same-origin`, `include`. Include cookies in request?
- `bailout`: function. Is always executed before performing a request and will abort if it evaluates to true.
fetchReducer(id)
id
: string uniquely identifying your fetch operation
const cached = !!state[id].payload && !force;
return state[id].loading || cached;
It will bail if it is already fetching data
or if it already has data and is not forced
.