# redux-modular

> Modular Redux helpers

Latest version **0.4.1** (published 2018-10-10) · MIT license · 0 weekly downloads

## Install

```sh
npm install redux-modular
pnpm add redux-modular
yarn add redux-modular
bun add redux-modular
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.4.1 |
| Published | 2018-10-10 |
| First published | 2017-09-30 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 1 |
| Unpacked size | 10.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 7 |
| Author | Thomas Dashney |
| Maintainers | thomasdashney |
| Keywords | redux, modular |

## Links

- npm: https://www.npmjs.com/package/redux-modular
- Repository: https://github.com/thomasdashney/redux-modular
- Homepage: https://github.com/thomasdashney/redux-modular#readme
- Issues: https://github.com/thomasdashney/redux-modular/issues
- npm.io page: https://npm.io/package/redux-modular

## Dependencies (1)

- [lodash.get](https://npm.io/package/lodash.get.md) ^4.4.2

## Recent versions

- 0.4.1 (latest) — 2018-10-10
- 0.4.0 — 2018-02-05
- 0.3.2 — 2017-10-04
- 0.3.1 — 2017-10-04
- 0.3.0 — 2017-10-02
- 0.2.0 — 2017-10-01
- 0.1.2 — 2017-09-30
- 0.1.1 — 2017-09-30
- 0.1.0 — 2017-09-30
- 0.0.2 — 2017-09-30
- 0.0.1 — 2017-09-30

## README

# redux-modular

Helpers for scaling and abstracting redux by co-locating actions, reducers and selectors.

[![Build Status](https://travis-ci.org/thomasdashney/redux-modular.svg?branch=master)](https://travis-ci.org/thomasdashney/redux-modular) [![Test Coverage](https://codeclimate.com/github/thomasdashney/redux-modular/badges/coverage.svg)](https://codeclimate.com/github/thomasdashney/redux-modular/coverage) [![Code Climate](https://codeclimate.com/github/thomasdashney/redux-modular/badges/gpa.svg)](https://codeclimate.com/github/thomasdashney/redux-modular)

## Install

```
$ npm install --save redux-modular
```

or

```
$ yarn add redux-modular
```

## Usage

<p align="center">
  <img src="https://raw.githubusercontent.com/thomasdashney/redux-modular/master/counter-example.png" />
</p>

```js
import { combineReducers, createStore } from 'redux'
import { mount, createReducer } from 'redux-modular'

/* Create an object containing the logic (actions, reducer, selectors) */

const counter = {
  // mapping of action names to optional payload creators
  actions: {
    increment: null,
    decrement: null,
    set: (value) => ({ value })
  },

  // function mapping actions to reducers
  reducer: actions => createReducer(0, {
    [actions.increment]: state => state + 1,
    [actions.decrement]: state => state - 1,
    [actions.set]: (state, payload) => payload.value
  }),

  // function mapping local state selector to your selectors
  selectors: localStateSelector => ({
    counterValue: state => localStateSelector(state)
  })
}

/* Instantiate the counter logic by mounting to redux paths */

const counter1 = mount('counter1', counter)
const counter2 = mount('counter2', counter)
const counter3 = mount(['nested', 'counter3'], counter)

/* Add the reducers to your root reducer */

const rootReducer = combineReducers({
  counter1: counter1.reducer,
  counter2: counter2.reducer,
  nested: combineReducers({
    counter3: counter3.reducer
  })
})

const store = createStore(rootReducer)

/* Use actions and selectors for each counter instance in your app */

const { actions, selectors } = counter1

console.log(selectors.counterValue(store.getState())) // prints `0`

store.dispatch(actions.increment())
console.log(selectors.counterValue(store.getState())) // prints `1`

store.dispatch(actions.decrement())
console.log(selectors.counterValue(store.getState())) // prints `0`

store.dispatch(actions.set(5))
console.log(selectors.counterValue(store.getState())) // prints `5`
```

## Writing Tests

If you `mount` your logic to a path of `null`, you can test your state logic without any assumption of where it sits in your redux state.

```js
/* eslint-env jest */

const counter = require('./counter')

const { actions, reducer, selectors } = mount(null, counter)

it('can increment', () => {
  const state = reducer(0, actions.increment())
  expect(selectors.counterValue(state)).toEqual(1)
})

it('can decrement', () => {
  const state = reducer(0, actions.decrement())
  expect(selectors.counterValue(state)).toEqual(-1)
})

it('can be set to a number', () => {
  const state = reducer(0, actions.set(5))
  expect(selectors.counterValue(state)).toEqual(5)
})
```

---
_Source: https://npm.io/package/redux-modular · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
