JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 803
  • Score
    100M100P100Q98888F
  • License MIT

Redux enhancer for pure detection of state changes.

Package Exports

  • redux-detector

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (redux-detector) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Redux Detector

Npm version Build Status Coverage Status tested with jest code style: prettier commitizen friendly

Redux enhancer for pure detection of state changes.

Warning: API is not stable yet, will be from version 1.0

Installation

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));

Motivation

Redux Detector enhancer allows you to detect state changes in redux. A detector is a simple and pure function which compares two states and returns action or list of actions for some states transitions.

type Detector<S> = (
  prevState: S | undefined,
  nextState: S | undefined
) => Action | Action[] | 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.

Composition

Redux store can handle only one detector (and one reducer). But don't worry - you can combine and reduce them. To do this, use combineDetectors and reduceDetectors functions.

// ./detectors/rootDetector.js
import { combineDetectors, reduceDetectors } 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: reduceDetectors(fooDetector, anotherDetector),
  bar: barDetector
});

Another way to re-use local state detectors is to mount them with mountDetector 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 { mountDetector } from "redux-detector";
import { createLimitExceeedDetector } from "./limitExceedDetector";

export const rowsLimitExceedDetector = mountDetector(
  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).

Code Splitting

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' }.

Typings

If you are using TypeScript, you don't have to install typings - they are provided in npm package.

License

MIT