UNPKG

redux-detector

Version:

Redux enhancer for pure detection of state changes.

161 lines (113 loc) β€’ 5.65 kB
<div align="center"> <h1>Redux Detector</h1> <p>Redux enhancer for pure detection of state changes πŸ‘€</p> [![npm version](https://img.shields.io/npm/v/redux-detector.svg)](https://www.npmjs.com/package/redux-detector) [![build Status](https://travis-ci.org/piotr-oles/redux-detector.svg?branch=master)](https://travis-ci.org/piotr-oles/redux-detector) [![coverage Status](https://coveralls.io/repos/github/piotr-oles/redux-detector/badge.svg?branch=master)](https://coveralls.io/github/piotr-oles/redux-detector?branch=master) [![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) [![commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) </div> ## Table of Contents πŸ“‹ - [Installation πŸ“¦](#installation) - [Concept πŸ’‘](#concept) - [Basics πŸ‘ˆ](#basics) - [API reference πŸ“–](doc/api.md) - [Code splitting βœ‚οΈ](#code-splitting️) - [Typings πŸ“](#typings) - [License](#license) ## Installation πŸ“¦ Redux Detector requires **Redux 3.1.0 or later.** ```sh npm install --save redux-detector ``` This assumes that you’re using [npm](http://npmjs.com/) package manager with a module bundler like [Webpack](https://webpack.js.org/) to consume [ES6](https://webpack.js.org/api/module-methods/#es6-recommended) or [CommonJS](https://webpack.js.org/api/module-methods/#commonjs) modules. To enable Redux Detector, use `createDetectorEnhancer`: ```js import { createStore } from "redux"; import { createDetectorEnhancer } from "redux-detector"; import { rootReducer } from "./store/reducer/rootReducer"; import { rootDetector } from "./store/detector/rootDetector"; const store = createStore(rootReducer, createDetectorEnhancer(rootDetector)); ``` ## Concept πŸ’‘ Redux Detector [enhancer](http://redux.js.org/docs/api/createStore.html) allows you to **detect state changes** in the Redux. The **`Detector`** is a pure function which accepts previous and next state and returns something for given states transition. ```typescript type Detector<TState, TResult> = ( prevState: TState | undefined, nextState: TState | undefined ) => TResult; ``` The **`Actions Detector`** is a `Detector` which returns action, list of actions or nothing. Returned actions are automatically dispatched by the enhancer. ```typescript import { Detector } from "redux-detector"; import { Action } from "redux"; type ActionsDetector<TState, TAction extends Action> = Detector< TState, TAction | TAction[] | void >; ``` Another type of the detector is the **`Condition Detector`** which returns boolean values. ```typescript import { Detector } from "redux-detector"; type ConditionDetector<TState> = Detector<TState, boolean>; ``` These two types of detectors have different responsibility: - `Condition Detectors` describes a condition that we want to detect - `Actions Detectors` describes which action we want to dispatch Thanks to its functional nature and purity, detectors are easy to test. They don't break [Single Source of Truth principle](https://en.wikipedia.org/wiki/Single_source_of_truth) as the input is only previous and next state. ## Basics πŸ‘ˆ Let's start simply - implement a condition detector that checks if number of login attempts exceeded 3. ```typescript export const exceededLoginAttemptsLimit = (prevState, nextState) => prevState.attempts <= 3 && nextState.attempts > 3; ``` We can make above example more generic - `prevState.attempts <= 3` is the same as `!(prevState.attempts > 3)`. That means that we check if some condition is **not truthy** for the _previous state_ but is **truthy** for the _next state_. This kind of transition can be handled by the `changedToTruthy` function. ```typescript import { changedToTruthy } from "redux-detector"; export const exceededLoginAttemptsLimit = changedToTruthy( state => state.attempts > 3 ); ``` > Redux Detector library provides other useful functions to model condition detectors - please check the > [API documentation](doc/api.md) to learn more. The next step is to use an action detector to dispatch an action when the limit became exceeded. To do so, we will use `composeIf` function. ```typescript import { composeIf, changedToTruthy } from "redux-detector"; import { blockUser } from "../action/userAction"; const blockUserDetector = composeIf( changedToTruthy(state => state.attempts > 3), () => blockUser() ); ``` The `createDetectorEnhancer` function accepts only one detector, so we have to compose all detectors to the one `rootDetector`. ```typescript import { composeDetectors } from "redux-detector"; import { blockUserDetector } from "./userDetector"; // other detectors... import { companyDetector } from "./companyDetector"; export const rootDetector = composeDetectors( blockUserDetector, companyDetector ); ``` And that's all - `redux-detector` will dispatch `blockUser()` when login attempts exceeded 3 πŸŽ‰ ## [API reference πŸ“–](doc/api.md) For more detailed documentation, please check API reference. ## 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](https://www.typescriptlang.org/), typings are provided in the npm package. This library doesn't provide [Flow](https://flow.org/) typings. ## License MIT