
Security News
ECMAScript 2025 Finalized with Iterator Helpers, Set Methods, RegExp.escape, and More
ECMAScript 2025 introduces Iterator Helpers, Set methods, JSON modules, and more in its latest spec update approved by Ecma in June 2025.
redux-detector
Advanced tools
Redux enhancer for pure detection of state changes.
Warning: API is not stable yet, will be from version 1.0
Redux Detector requires Redux 3.1.0 or later.
npm install --save redux-detector
This assumes that you’re using npm package manager with a module bundler like Webpack or Browserify to consume CommonJS modules.
To enable Redux Detector, use createDetectorEnhancer
:
import { createStore } from "redux";
import { createDetectorEnhancer } from "redux-detector";
import rootReducer from "./reducers";
import rootDetector from "./detectors";
const store = createStore(rootReducer, createDetectorEnhancer(rootDetector));
Redux Detector enhancer allows you to detect state changes in the redux. An actions detector is a simple and pure function which compares two states and returns action or list of actions for given states transitions.
type ActionsDetector<TState, TAction extends Action = AnyAction> = (
prevState: TState | undefined,
nextState: TState | undefined
) => TAction | TAction[] | void;
For example detector that checks if number of rows exceed 100 looks like this:
function rowsLimitExceededDetector(prevState, nextState) {
if (prevState.rows.length <= 100 && nextState.rows.length > 100) {
return { type: ROWS_LIMIT_EXCEEDED };
}
}
You can also return an array of actions or nothing (undefined). Thanks to detectors purity they are predictable and easy to test. There is no problem with features like time-travel, etc.
Redux store can handle only one detector (and one reducer). But don't worry - you can combine and compose them. To do this, use
combineDetectors
and composeDetectors
functions.
// ./detectors/rootDetector.js
import { combineDetectors, composeDetectors } from "redux-detector";
import { fooDetector } from "./fooDetector";
import { barDetector } from "./barDetector";
import { anotherDetector } from "./anotherDetector";
// our state has shape:
// {
// foo: [],
// bar: 1
// }
//
// We want to bind `fooDetector` and `anotherDetector` to `state.foo` branch (they should run in sequence)
// and also `barDetector` to `state.bar` branch.
export default combineDetectors({
foo: composeDetectors(fooDetector, anotherDetector),
bar: barDetector
});
Another way to re-use local state detectors is to mount them with mapState
function. Combine detectors work only on objects level -
if you want to use detectors on more nested data, you should mount them. With factory pattern, it becomes very elastic.
// ./detectors/limitExceedDetector.js
export function createLimitExceedDetector(limit, action) {
return function limitExceedDetector(prevState, nextState) {
if (prevState <= limit && nextState > limit) {
return action;
}
};
}
// ./detectors/rowsLimitExceedDetector.js
import { mapState } from "redux-detector";
import { createLimitExceeedDetector } from "./limitExceedDetector";
export const rowsLimitExceedDetector = mapState(
state => state.rows.length,
createLimitExceedDetector(100, ROWS_LIMIT_EXCEEDED)
);
Of course, examples above are very trivial, but you can use it to solve more common problems (you can, for example, schedule resource fetch on parameters change).
The most common use case is to detect if some condition has been changed. As the condition can become very complex, this library provides few functions that helps to create such detectors.
That's how we can implement detector that will fetch users list if we are on the users page and pagination or filters changed:
import {
conditionDetector,
composeOr,
composeAnd,
mapState,
mapNextState,
changedPositive
} from "redux-detector";
import { hasMatch } from "./routerSelectors";
import { getUserPagination, getUserFilters } from "./userSelectors";
import { fetchUsers } from "./userActions";
import { USERS_ROUTE } from "./routes";
const usersListDetector = conditionDetector(
composeOr(
mapState(hasMatch(USERS_ROUTE), changedPositive), // case 1 - we have entered users page
composeAnd(
// case 2 - we are on the users page and pagination or filters changed
mapNextState(hasMatch(USERS_ROUTE)),
composeOr(
mapState(getUserPagination, changedPositive),
mapState(getUserFilters, changedPositive)
)
)
),
() => fetchUsers()
);
Redux Detector provides replaceDetector
method on DetectableStore
interface (store created by Redux Detector). It's similar to
replaceReducer
- it changes detector and dispatches { type: '@@detector/INIT' }
.
If you are using TypeScript, you don't have to install typings - they are provided in npm package.
MIT
FAQs
Redux enhancer for pure detection of state changes.
The npm package redux-detector receives a total of 1,054 weekly downloads. As such, redux-detector popularity was classified as popular.
We found that redux-detector demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
ECMAScript 2025 introduces Iterator Helpers, Set methods, JSON modules, and more in its latest spec update approved by Ecma in June 2025.
Security News
A new Node.js homepage button linking to paid support for EOL versions has sparked a heated discussion among contributors and the wider community.
Research
North Korean threat actors linked to the Contagious Interview campaign return with 35 new malicious npm packages using a stealthy multi-stage malware loader.