Skip to content

Commit

Permalink
createReducer utility
Browse files Browse the repository at this point in the history
  • Loading branch information
Asaf Shakarzy committed Sep 4, 2015
1 parent a654e7d commit 68f59d3
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 6 deletions.
41 changes: 39 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
# `redux-immutablejs`

An alternative to [combineReducers](http://rackt.github.io/redux/docs/api/combineReducers.html) that supports
[ImmutableJs](https://facebook.github.io/immutable-js/).
Redux & Immutable integration

This is a small library that aims to provide integration tools between [Redux](https://github.com/rackt/redux)
& [ImmutableJs](https://facebook.github.io/immutable-js/) that fully conforms Redux _actions_ & _reducers_ standards.

1. An alternative to [combineReducers](http://rackt.github.io/redux/docs/api/combineReducers.html) that supports
[ImmutableJs](https://facebook.github.io/immutable-js/) for store initial state.
1. An optional handler map reducer creator with immutable support.


# Setup

Expand All @@ -23,6 +30,36 @@ const state = reducer(state);
export default createStore(reducer, state);
```

## Immutable Handler Map reducer creator

Using `createReducer` is an optional function that creates a reducer from a collection of handlers, except
getting ride of the _switch_ statement, it also provides the following benefits:

1. If the given `initialState` type is mutated, it will get converted to an immutable type.
1. An error is produced in case a reducer handler returns a mutated state (not recommended but this behavior can be disabled)

```js
import { createReducer } from 'redux-immutablejs'
const initialState = Immutable.fromJS({ isAuth: false })

/**
* Reducer domain that handles authentication & authorization.
**/
export default createReducer(initialState, {
[LOGIN] (state, action) {
return state.merge({ 'isAuth': true, token: action.payload.token })
},

[LOGOUT] (domain) {
return domain.merge({ 'isAuth': false, 'current_identity': {}, token: undefined })
}
})
```


Please note that this is optional and `combineReducers` should work just fine if you prefer the old `switch` way.


# FAQ

## How this library is different from 'redux-immutable' ?
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "redux-immutable",
"name": "redux-immutablejs",
"version": "0.0.1",
"description": "Redux Immutable facilities",
"scripts": {
Expand All @@ -14,7 +14,7 @@
"author": "Indexia Tech",
"license": "BSD-3-Clause",
"bugs": {
"url": "https://github.com/indexiatech/redux-immutable/issues"
"url": "https://github.com/indexiatech/redux-immutablejs/issues"
},
"homepage": "http://indexiatech.github.io/redux-immutable",
"peerDependencies": {
Expand Down
6 changes: 4 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import combineReducers from './utils/combineReducers';
import createReducer from './utils/createReducer';

export {
combineReducers
}
combineReducers,
createReducer
};
34 changes: 34 additions & 0 deletions src/utils/createReducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Immutable from 'immutable';

/**
* Create a handler (action) map reducer for the given list of handlers
*
* @param {object} initialState The initial state of the reducer, expecting an Immutable.Iterable instance,
* otherwise given initialState is converted to immutable.
* @param {object} handlers A map of actions where key is action name and value is a reducer function
* @param {boolean} enforceImmutable = true if to enforce immutable, in other words a TypeError is thrown in case
* a handler returned anything that is not an Immutable.Iterable type.
* @return {object} The calculated next state
*/
export default function createReducer(initialState, handlers, enforceImmutable = true) {
return (state = initialState, action) => {
// convert the initial state to immutable
if (!Immutable.Iterable.isIterable) {
state = Immutable.fromJS(state);
}

const handler = (action && action.type) ? handlers[action.type] : undefined;

if (!handler) {
return state;
}

state = handler(state, action);

if (enforceImmutable && !Immutable.Iterable.isIterable(state)) {
throw new TypeError('Reducers must return Immutable objects.');
}

return state;
};
}

0 comments on commit 68f59d3

Please sign in to comment.