Skip to content

Commit

Permalink
Merge pull request #2 from maxmechanic/include-actions
Browse files Browse the repository at this point in the history
Add higher-order reducer for including only specific actions
  • Loading branch information
omnidan committed Oct 20, 2015
2 parents 3963b56 + 5c2fec0 commit d11a657
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 23 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ npm install --save redux-ignore
## API

```js
import ignoreActions from 'redux-ignore';
import { ignoreActions, filterActions } from 'redux-ignore';

ignoreActions(reducer, [ARRAY_OF_ACTIONS])
ignoreActions(reducer, (action) => !action.valid)

filterActions(reducer, [ARRAY_OF_ACTIONS])
filterActions(reducer, (action) => action.valid)
```


Expand All @@ -35,7 +39,7 @@ Firstly, import `redux-ignore`:
// Redux utility functions
import { combineReducers } from 'redux';
// redux-ignore higher-order reducer
import ignoreActions from 'redux-ignore';
import { ignoreActions } from 'redux-ignore';
```

Then, add `ignoreActions` to your reducer(s) like this:
Expand All @@ -57,6 +61,20 @@ combineReducers({
});
```

You can also use `filterActions` to only accept actions that are declared in an array, or that satisfy the predicate function:

```js
import { combineReducers } from 'redux';
import { filterActions } from 'redux-ignore'; // pull in the filterActions function
import { STAY_COOL, KEEP_CHILLIN } from './actions';

combineReducers({
counter: filterActions(counter, (action) => action.type.match(/COUNTER$/)), // only run on actions that satisfy the regex
notACounter: filterActions(notACounter, [STAY_COOL, KEEP_CHILLIN]) // only run for these specific relaxing actions
});

```

## What is this magic? How does it work?

Have a read of the [Implementing Undo History recipe](https://rackt.github.io/redux/docs/recipes/ImplementingUndoHistory.html)
Expand Down
28 changes: 18 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import isFunction from 'lodash/lang/isFunction'

// redux-ignore higher order reducer
export default function ignoreActions (reducer, actions = []) {
let ignorePredicate = isFunction(actions)
? actions
: (action) => actions.indexOf(action.type) >= 0
function createActionHandler (ignore) {
// redux-ignore higher order reducer
return function handleAction (reducer, actions = []) {
const predicate = isFunction(actions)
? actions
: (action) => actions.indexOf(action.type) >= 0

return (state, action) => {
if (!ignorePredicate(action)) {
return reducer(state, action)
}
return (state, action) => {
if (predicate(action)) {
return ignore ? state : reducer(state, action)
}

return state
return ignore ? reducer(state, action) : state
}
}
}

export const ignoreActions = createActionHandler(true)
export const filterActions = createActionHandler(false)

export default ignoreActions
// /redux-ignore

60 changes: 49 additions & 11 deletions test/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import assert from 'assert'
import ignoreActions from '../src/index'
import { ignoreActions, filterActions } from '../src/index'

describe('ignoreActions()', () => {
let reducer = (state, action) => {
switch (action.type) {
case 'FOO':
return 'foo-state'
case 'BAR':
return 'bar-state'
default:
return 'default-state'
}
let reducer = (state, action) => {
switch (action.type) {
case 'FOO':
return 'foo-state'
case 'BAR':
return 'bar-state'
default:
return 'default-state'
}
}

describe('ignoreActions()', () => {
it('should ignore actions with specified types in array', () => {
let ignoringReducer = ignoreActions(reducer, ['BAR'])
let action = { type: 'BAR' }
Expand Down Expand Up @@ -49,3 +49,41 @@ describe('ignoreActions()', () => {
'testing')
})
})

describe('filterActions()', () => {
it('should include actions with specified types in array', () => {
let filteringReducer = filterActions(reducer, ['BAR'])
let action = { type: 'BAR' }

assert.equal(
filteringReducer('testing', action),
'bar-state')
})

it('should exclude actions that do not have types in array', () => {
let filteringReducer = filterActions(reducer, ['BAR'])
let action = { type: 'FOO' }

assert.equal(
filteringReducer('testing', action),
'testing')
})

it('should exclude all actions when no action types array is specified', () => {
let filteringReducer = filterActions(reducer)
let action = { type: 'BAZ' }

assert.equal(
filteringReducer('testing', action),
'testing')
})

it('should work with a predicate function for actions', () => {
let filteringReducer = filterActions(reducer, (a) => a.valid)
let action = { type: 'BAR', valid: true }

assert.equal(
filteringReducer('testing', action),
'bar-state')
})
})

0 comments on commit d11a657

Please sign in to comment.