Redux Promise Middleware
raw JSON →Redux Promise Middleware is a Redux middleware that simplifies the handling of asynchronous actions by transforming actions containing Promises into a series of pending, fulfilled, and rejected actions. This allows for clear separation of concerns in Redux applications, enabling robust state management during async operations. The current stable version is 6.2.0, which includes support for Redux 5.0.0 and earlier versions. The library maintains an active release cadence, addressing bugs, improving TypeScript definitions, and ensuring compatibility with newer Redux versions. Key differentiators include its ability to work seamlessly with Redux Thunk for complex action chaining and its configurable action type delimiters, providing granular control over action naming conventions for lifecycle events.
Common errors
error TypeError: (0 , _reduxPromiseMiddleware.default) is not a function ↓
applyMiddleware(promiseMiddleware). error Error: Actions may not have an undefined 'type' property. Have you misspelled a constant? ↓
payload that is a valid Promise object. Check your action creators for correct structure. error Property 'promiseTypeSeparator' does not exist on type 'PromiseMiddlewareOptions'. Did you mean 'promiseTypeDelimiter'? ↓
promiseTypeSeparator to promiseTypeDelimiter in your middleware configuration object. Warnings
breaking The default export changed from a middleware factory function to the preconfigured middleware itself. You no longer call `promiseMiddleware()` when applying it. ↓
breaking The configuration property `promiseTypeSeparator` was renamed to `promiseTypeDelimiter` for improved semantic accuracy. ↓
gotcha Early versions of v6.x had issues with TypeScript definitions not being correctly published or having incorrect typings for `ActionType`. ↓
gotcha When combining with Redux Thunk, dispatching the promise action will return the promise itself. This allows chaining further actions, but be mindful of error handling in the chain. ↓
Install
npm install redux-promise-middleware yarn add redux-promise-middleware pnpm add redux-promise-middleware Imports
- promiseMiddleware wrong
import { promiseMiddleware } from 'redux-promise-middleware'correctimport promiseMiddleware from 'redux-promise-middleware' - createPromiseMiddleware wrong
import { createPromiseMiddleware } from 'redux-promise-middleware'correctimport promiseMiddleware from 'redux-promise-middleware' // Use promiseMiddleware directly, no need to call a creator function anymore - ActionType wrong
import { ActionType } from 'redux-promise-middleware'correctimport type { ActionType } from 'redux-promise-middleware'
Quickstart
import { createStore, applyMiddleware, combineReducers } from 'redux';
import promiseMiddleware from 'redux-promise-middleware';
// A simple reducer
const dataReducer = (state = { data: null, loading: false, error: null }, action) => {
switch (action.type) {
case 'FETCH_DATA_PENDING':
return { ...state, loading: true, error: null };
case 'FETCH_DATA_FULFILLED':
return { ...state, loading: false, data: action.payload };
case 'FETCH_DATA_REJECTED':
return { ...state, loading: false, error: action.payload };
default:
return state;
}
};
const rootReducer = combineReducers({
data: dataReducer,
});
// Create the Redux store with promiseMiddleware
const store = createStore(rootReducer, applyMiddleware(promiseMiddleware));
// An async action creator
const fetchData = () => ({
type: 'FETCH_DATA',
payload: new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.5;
if (success) {
resolve('Hello from async data!');
} else {
reject(new Error('Failed to fetch data.'));
}
}, 1000);
}),
});
console.log('Initial state:', store.getState());
store.dispatch(fetchData());
store.subscribe(() => {
console.log('Current state:', store.getState());
});