redux-requests
Declarative AJAX requests and automatic network state management for single-page applications
Just actions
Just dispatch actions and enjoy automatic AJAX requests and network state management
First class aborts support
Automatic and configurable requests aborts, which increases performance and prevents race condition bugs before they even happen
Drivers driven
Compatible with anything for server communication. Axios, Fetch API, GraphQL, promise libraries, mocking? No problem! You can also integrate it with other ways by writing a custom driver!
Batch requests
Define multiple requests in single action
Optimistic updates
Update remote data before receiving server response to improve perceived performance
Cache
Cache server response forever or for a defined time period to decrease amount of network calls
Data normalisation
Use automatic data normalisation in GraphQL Apollo fashion, but for anything, including REST!
Server side rendering
Configure SSR totally on Redux level and write truly universal code between client and server
React bindings
Use react bindings to decrease code amount with React even more
With redux-requests, assuming you use axios (you could use it with anything else too!) you could refactor a code in the following way:
import axios from 'axios';- import thunk from 'redux-thunk';+ import { handleRequests } from '@redux-requests/core';+ import { createDriver } from '@redux-requests/axios'; // or another driverconst FETCH_BOOKS = 'FETCH_BOOKS';- const FETCH_BOOKS_SUCCESS = 'FETCH_BOOKS_SUCCESS';- const FETCH_BOOKS_ERROR = 'FETCH_BOOKS_ERROR';-- const fetchBooksRequest = () => ({ type: FETCH_BOOKS });- const fetchBooksSuccess = data => ({ type: FETCH_BOOKS_SUCCESS, data });- const fetchBooksError = error => ({ type: FETCH_BOOKS_ERROR, error });- const fetchBooks = () => dispatch => {- dispatch(fetchBooksRequest());-- return axios.get('/books').then(response => {- dispatch(fetchBooksSuccess(response.data));- return response;- }).catch(error => {- dispatch(fetchBooksError(error));- throw error;- });- }+ const fetchBooks = () => ({+ type: FETCH_BOOKS,+ request: {+ url: '/books',+ // you can put here other Axios config attributes, like method, data, headers etc.+ },+ });- const defaultState = {- data: null,- pending: 0, // number of pending FETCH_BOOKS requests- error: null,- };-- const booksReducer = (state = defaultState, action) => {- switch (action.type) {- case FETCH_BOOKS:- return { ...defaultState, pending: state.pending + 1 };- case FETCH_BOOKS_SUCCESS:- return { ...defaultState, data: action.data, pending: state.pending - 1 };- case FETCH_BOOKS_ERROR:- return { ...defaultState, error: action.error, pending: state.pending - 1 };- default:- return state;- }- };const configureStore = () => {+ const { requestsReducer, requestsMiddleware } = handleRequests({+ driver: createDriver(axios),+ });+const reducers = combineReducers({- books: booksReducer,+ requests: requestsReducer,});const store = createStore(reducers,- applyMiddleware(thunk),+ applyMiddleware(...requestsMiddleware),);return store;};
Would you like to learn more?