Redux Hub Middleware
raw JSON →This Redux middleware addresses the challenge of managing multiple, isolated Redux stores within a single application, a common pattern in large React/Redux projects with distinct sub-applications. It provides a mechanism, a 'hub', to re-dispatch actions across all connected stores, effectively synchronizing state changes that originate from any single store. The current stable version is 1.0.4. While the package hasn't seen recent major updates since its initial releases, its core functionality remains relevant for specific multi-store architectures. Its key differentiator is providing a simple, explicit hub for action propagation without merging states or requiring complex global state management solutions, allowing individual stores to retain their isolation while enabling cross-store communication.
Common errors
error TypeError: hub.connect is not a function ↓
createReduxHub() to get the hub instance: const hub = createReduxHub(); error Store state not synchronizing across connected stores ↓
applyMiddleware(hub.middleware) is used when creating each store, and that hub.connect(store) is explicitly called for every store intended to participate in the hub. error Warning: Middleware for RTK-Query API at reducerPath "..." has not been added to the store. ↓
configureStore call to include getDefaultMiddleware() when adding redux-hub-middleware: middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(hub.middleware). Warnings
gotcha Actions dispatched through the hub are re-dispatched to *all* connected stores. Ensure your reducers are designed to handle actions appropriately, or you may experience unintended state changes across stores that should remain isolated from certain actions. ↓
gotcha This package uses the `createStore` and `applyMiddleware` functions from the core `redux` library, which are considered legacy in modern Redux development. Redux Toolkit's `configureStore` is the recommended approach. While functionally compatible, integrating `redux-hub-middleware` with `configureStore` requires careful manual middleware configuration. ↓
gotcha Performance may be impacted in applications with a very large number of connected stores or extremely high-frequency action dispatches, as each action is processed and re-dispatched potentially multiple times across the hub. ↓
breaking Redux v5.0.0 and Redux Toolkit v2.0.0 introduced changes to middleware typing, where `action` and `next` parameters are typed as `unknown`. Middleware written against older Redux types might require updates to explicitly type-guard actions. While `redux-hub-middleware` itself is unlikely to break, custom middleware used in conjunction with it might. ↓
Install
npm install redux-hub-middleware yarn add redux-hub-middleware pnpm add redux-hub-middleware Imports
- createReduxHub wrong
import { createReduxHub } from 'redux-hub-middleware';correctimport createReduxHub from 'redux-hub-middleware'; - connect wrong
import { connect } from 'redux-hub-middleware';correctimport createReduxHub from 'redux-hub-middleware'; const { connect } = createReduxHub(); - middleware wrong
import { middleware } from 'redux-hub-middleware';correctimport createReduxHub from 'redux-hub-middleware'; const { middleware } = createReduxHub(); - CommonJS require wrong
const { createReduxHub } = require('redux-hub-middleware');correctconst createReduxHub = require('redux-hub-middleware'); const { connect, middleware } = createReduxHub();
Quickstart
import { createStore, applyMiddleware } from 'redux';
import createReduxHub from 'redux-hub-middleware';
// Create a Redux Hub instance
const hub = createReduxHub();
// Define two simple reducers for separate stores
function reducer1(state = 'Store 1 initial state', action) {
if (action.type === 'CHANGE_VALUE') {
return action.payload;
}
return state;
}
function reducer2(state = 'Store 2 initial state', action) {
if (action.type === 'CHANGE_VALUE') {
return action.payload;
}
return state;
}
// Create two Redux stores, each applying the hub's middleware
const store1 = createStore(reducer1, applyMiddleware(hub.middleware));
const store2 = createStore(reducer2, applyMiddleware(hub.middleware));
// Connect both stores to the Redux Hub
hub.connect(store1);
hub.connect(store2);
console.log('Initial State Store 1:', store1.getState());
console.log('Initial State Store 2:', store2.getState());
// Dispatch an action on store1
store1.dispatch({ type: 'CHANGE_VALUE', payload: 'Value changed by Store 1' });
console.log('After Store 1 dispatch:');
console.log('Store 1:', store1.getState()); // Should reflect change
console.log('Store 2:', store2.getState()); // Should also reflect change due to hub
// Dispatch an action on store2
store2.dispatch({ type: 'CHANGE_VALUE', payload: 'Value changed by Store 2' });
console.log('After Store 2 dispatch:');
console.log('Store 1:', store1.getState()); // Should reflect change
console.log('Store 2:', store2.getState()); // Should also reflect change