An open API service indexing awesome lists of open source software.

https://github.com/xuoe/redux-observers

Observe Redux state changes and dispatch actions on change
https://github.com/xuoe/redux-observers

Last synced: 2 months ago
JSON representation

Observe Redux state changes and dispatch actions on change

Awesome Lists containing this project

README

        

# redux-observers

[![Build Status](https://img.shields.io/github/actions/workflow/status/xuoe/redux-observers/ci.yml?style=flat-square)](https://github.com/xuoe/redux-observers/actions/workflows/ci.yml)
[![Coverage Status](https://img.shields.io/coveralls/xuoe/redux-observers.svg?style=flat-square)](https://coveralls.io/r/xuoe/redux-observers)
[![NPM Version](https://img.shields.io/npm/v/redux-observers.svg?style=flat-square)](https://www.npmjs.com/package/redux-observers)

Observe [Redux](http://redux.js.org/) state changes and dispatch actions on change.

## Installation

Assuming you're using `npm` and a module bundler capable of consuming CommonJS
modules:

`npm install --save redux-observers`

## Usage
First, create a `store` object as you normally would, then create the necessary
observers and pass them as arguments to `observe()`:

```javascript
import { observer, observe } from 'redux-observers'

const myObserver = observer(
state => state.slice.of.interest,
(dispatch, current, previous) => {
expect(previous).to.be.ok()
expect(current).to.not.eql(previous)
dispatch({ type: 'SLICE_CHANGE', payload: {...} })
}
)

observe(store, [myObserver, ...myOtherObservers])
```

That's the gist of it.

## API

#### `observer([mapper], dispatcher, [options]) => observerFunc`

Creates an observer.

- `mapper(state) => mappedState` *(Function)*

Specifies which state slice(s) should be observed by returning a plain
object (or any other value) extracted from the store's state. It is similar
in vein to `mapStateToProps()` provided by `react-redux`.

If no `mapper` is provided, the entire store state is mapped by default.

- `dispatcher(dispatch, currentState, [previousState])` *(Function)*

Called whenever the mapped-over state changes. Note that `previousState`
may be omitted from the `dispatcher` signature if desired.

- `options` *(Object)*

A local options object, whose values are applicable only in the context of
the returned `observerFunc`. Any option provided here takes precedence over
its [global](#observestore-observers-options--unsubscribefunc)
and [default](#options) equivalents.

_Note that if care is not exercised, infinite cycles may be created between
a `mapper` and a `dispatcher`._

#### `observe(store, observers, [options]) => unsubscribeFunc`

Listens for `store` updates and applies given `observers` over the `store`
state.

- `store` *(Object)*

The Redux store object.

- `observers` *(Array)*

An array of (observer) functions, where each member must be the result of
calling `observer()`.

- `options` *(Object)*

A global options object, whose values are applicable only in the context
of the provided `observers` (i.e., `observe()`ing a `store` multiple times
using the same `observers`, but providing different global options, results
in a different behavior, as prescribed by that `options` object). Any option
provided here takes precedence over [its default value](#options).

##### Options

A plain object that may be provided to `observe(,, options)` to describe how
a set of observers must behave, or to `observer(,, options)` to describe how
a particular observer must behave.

- `skipInitialCall` *(Boolean, defaults to `true`)*

Specifies whether dispatchers must be called immediately after Redux
dispatches its `@@redux/INIT` action.

If set to `false`, dispatchers are initially called with an `undefined`
"previous" state; otherwise, and by default, a dispatcher is only called
after the "previous" state is set (i.e., after `@@redux/INIT` is
dispatched and the store's reducers had a chance to return their initial
state).

- `equals: (currentState, previousState) => Boolean` *(Function, defaults to `shallowEquals`)*

Specifies how the previous state should be compared with the current one. Its
return value must be a Boolean, which is used to determine whether a dispatcher
should be called. Note that, by default, values are compared in a shallow
manner via [`shallowEquals()`](#shallowequalsa-b--boolean), which should
satisfy most use cases.

#### `shallowEquals(a, b) => Boolean`

The default comparsion helper used by observers to determine whether two
mapped-over values (be they plain objects or primitive values) are equal.