Remove boilerplate around requests... just ask!
Redux Ask is a Redux library that simplifies requests and removes the boilerplate. There's no need to create new state or flags for every request anymore!
yarn add redux-ask
Pass the provided reducer to the store under the requests
key...
import { createStore, combineReducers } from 'redux';
import requestReducer from 'redux-ask';
const reducers = combineReducers({
requests: requestReducer,
});
const store = createStore(reducers);
Before you can send requests, you'll need to use the provided createRequest
helper to define a request...
import { createRequest } from 'redux-ask';
export const createUser = createRequest(user => ({
method: 'POST',
url: '/api/users',
body: user,
}));
To handle the response, use the onSuccess
and onFailure
thunk handlers. You can use this opportunity to normalize entities, pass entities to your state, or notify users of errors...
import { createRequest } from 'redux-ask';
import { receiveUser } from './user-actions';
export const createUser = createRequest(user => ({
method: 'POST',
url: '/api/users',
body: user,
onSuccess: (response) => dispatch => {
const newUser = response.result;
dispatch(receiveUser(newUser));
},
onFailure: () => dispatch => {
dispatch(displayNotification('There was an error creating a user'));
},
}));
If you want to configure your request, use the options
parameter. This will be passed as the fetch init
parameter (see documentation).
import { createRequest } from 'redux-ask';
export const createUser = createRequest(user => ({
method: 'POST',
url: '/api/users',
body: user,
options: {
headers: new Headers({
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
}),
credentials: 'include',
},
}));
In order to send the request, you'll need to wrap the created requests in dispatch and pass a UNIQUE request key...
import React from 'react';
import { connect } from 'redux-actions';
import { createUser } from './user-requests';
const CreateUserButton = ({ createUser, user }) => {
return (
<button onClick={() => createUser(user)}>
Create User
</button>
)
}
const UNIQUE_REQUEST_KEY = 'REQUEST_KEY';
const mapDispatchToProps = {
createUser: createUser(UNIQUE_REQUEST_KEY),
};
export default connect(null, mapDispatchToProps)(CreateUserButton);
If you would like to check the status of your request, use our selectors with the same UNIQUE request key...
import { selectors } from 'redux-ask';
// UNIQUE_REQUEST_KEY === 'REQUEST_KEY';
const mapStateToProps = state => {
return {
isNotStarted: selectors.isNotStartedSelector(UNIQUE_REQUEST_KEY)(state),
isPending: selectors.isPendingSelector(UNIQUE_REQUEST_KEY)(state),
isSuccessful: selectors.isSuccessfulSelector(UNIQUE_REQUEST_KEY)(state),
isFailed: selectors.isFailedSelector(UNIQUE_REQUEST_KEY)(state),
};
}
BOOM!
Most Apps use common configuration for all requests made. Redux Ask allows you to set a global configuration that will be used for all requests.
To set the global configuration, use the provided setRequestConfig
action...
import React, { Component } from 'react';
import { actions } from 'redux-ask';
class App extends Component {
componentWillMount() {
this.props.setRequestConfig({
options: { ... },
onSuccess: () => dispatch => { ... },
onFailure: () => dispatch => { ... },
onUnauthenticated: () => dispatch => { ... },
});
}
}
const mapDispatchToProps = {
setRequestConfig: actions.setRequestConfig,
};
Make sure to set the Global Configuration before any requests are made!
createRequest(requestConfigCreator:Func)
Creates a request that can be dispatched when given a Request Key.
setRequestConfig(config:Object)
Sets the global configuration for all requests.
statusSelector(requestKey:String)(state:Object)
Gets the status of a request.
isNotStartedSelector(requestKey:String)(state:Object)
Returns if the request has been started or not.
isPendingSelector(requestKey:String)(state:Object)
Returns if the request is currently pending.
isSuccessfulSelector(requestKey:String)(state:Object)
Returns if the request is finished and successful.
isFailedSelector(requestKey:String)(state:Object)
Returns if the request is finished and failed.
allStatusSelector(requestKey:String)(state:Object)
Gets all of the request status in an object. This is a nice helper if you are checking all status.
responseSelector(requestKey:String)(state:Object)
Returns if the response of the request if finished and successful.
errorSelector(requestKey:String)(state:Object)
Returns if the response of the request if finished and failed.
We have a few examples under our /examples
directory. To try them out, simply run the following commands.
cd examples/<example_directory>
yarn
yarn start
A browser should open up where you can interact with the example!
Please report any issues! I will glady accept them at our issues page.
- Fork it (https://github.com/TaeKimJR/redux-ask/fork)
- Create your feature branch (
git checkout -b feature/fooBar
) - Commit your changes (
git commit -am 'Add some fooBar'
) - Push to the branch (
git push origin feature/fooBar
) - Create a new Pull Request
Tae Kim – Github - LinkedIn – TaeKimJR@gmail.com
Distributed under the MIT license. See LICENSE
for more information.