npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

redux-action-hooks

v2.1.0

Published

Simple hook for Redux actions to create side effects

Downloads

1

Readme

redux-hooks

Simple middleware for side effects in redux

Inspiration

This is inspired by Angular's side effects based on RXJS without all rx library. Redux already has an ability to observe the incoming redux actions and exposes the middleware for the side effects. This library creates very simple API to interact with redux action flow and create simple clear and testable logic.

example

export const topUpEffect = ({ action, dispatch }) => {
  if(action.payload.amount > 100) {
    api.post(URL, action.payload)
    .then((payload) => {
      dispatch(topUpSuccess(payload))
    })
  }
}

ofType('ACCOUNT_TOPUP_REQUEST', topUpEffect)

This simplifies testing and decouples any asnchronous code or third party logic from the redux flow from action creator to reducer

How it works

This is Redux middleware

This middleware calls next(action) as the first statement, so your hook is executed AFTER any other middleware in the pipe which is added subsequently. However, this tool is designed for side effects which are not dependent on the sequence how the middleware is executed.

This library is intended for application with single redux store or if the application has more then one redux store, it will work only with one of them.

It is initialized as any other redux middleware by passing the Hooks into the createMiddleware function

import Hooks from 'redux-action-hooks'

const store = createStore(reducer, applyMiddleware(...othermiddleware, Hooks));

To hook the side effect every hook needs to be registered once. Depending on directory structure it can be run from the createStore file, or if application grows larger it is good idea to store the hooks together with reducers.

.
..
action_creators.js
action_types.js
reducer.js
effects.js

in reducer:

import './hooks.js'

the above code in reducer.js will register all hooks once, since the reducer.js code is executed only once.

Examples

ofType

Observes the type of the action and allows to execute extra logic if the action is in the redux flow.

NOTE - modifying action is not recommended. It can yield unexpected results.

import { ofType } from 'redux-action-hooks'

ofType('action_type_one', ({ action, getState, dispatch }) => {
  console.log(`Hello triggered by "${action.type}".`)
})

// running somewhere in the code will cause the following console output
dispatch({ action_type_one })

> Hello triggered by "action_type_one".

// passing multiple actions will cause the function 'runSideEffect'
// to be executed whenever any action in the list is dispatched
ofType(['action_type_one', 'action_type_two'], runSideEffect);

pipe

pipe simply dispatches another action with the identical payload to the first action(s)

import { pipe } from 'redux-action-hooks'

pipe(['action_type1'], 'action_type2')

ofType('action_type2', () => { console.log('hello world') })

//running somewhere in the code:
dispatch({ type: action_type1 }) // will create console output

> hello world

allCalled

oberves all action given in the array, and exectues the side effects only after all of them had been called at least once. The hook takes opional parameter in the form of { cleanup: boolean } which indicates whether to cleanup the call history once the side effect is run. If not given or set to false the side offect will run on every subseqent call of any given action passed into the hook. #####expample

import { allCalled } from 'redux-action-hooks'

allCalled(['action_A', 'action_B'], () => {  console.log('hello world') }, { cleanup: false })

dispatch({ type: action_A });
// no console output
dispatch({ type: action_B })
> hello world
dispatch({ type: action_A });
> hello world // prints hello world again
allCalled(['action_A', 'action_B'], () => {  console.log('hello world') }, { cleanup: true })

dispatch({ type: action_A });
// no console output
dispatch({ type: action_B })
> hello world
dispatch({ type: action_A });
// no console output
dispatch({ type: action_B })
> hello world

Required

Redux is the only dependency. More specifically it is @types/redux (or types from redux if supplied), However if you are not using typescript, there is no 3rd party dependency besides it is expected to be used with Redux middleware.

How to use it

Installation

npm install redux-action-hooks

Usage

if using redux-thunk this need to go after thunk in the pipeline

ideally hooks will sit in separate file some-hooks.ts (some-hooks.js) along the other redux files (reducers, action creators)

and will be called in the beginning of dedicated reducer

in MyReducer:

import './some-hooks'

which will hook the side effect to the action.

ofType([ActionTypes.PDF_DOCUMENT_FOLDER_SELECTED], ({ action: AnyAction, dispatch: Dispatch }) => {
  someSideEffectCode();
  dispatch({ type: 'other_action' })
})

It is possibe to hook to multiple actions at the same time. e.g. if the app need to perform logout after security breach or after user logout action

ofType([SecurityTypes.INVALIDATE_SESSION, UserAction.LOGOUT], ({ action: AnyAction }) => {
  makeSessionInvalid();
  setLocation('/login');
})

Testing

the effects are here to imporove the testability of the code traditional approach - all the async logic is in action creator

const export myFetchAction = (url) => (dispatch, getState) => {
  dispatch(startFetch());
  myService.fetch(action.payload.url)
    .then((result) => {
      dispatch(successAction(result))
    })
    .catch((error) => {
      dispatch(errorAction(error))
    })
}
export const mySideEffect = ({ action, dispatch, getState }) => {
  myService.fetch(action.payload.url)
    .then((result) => {
      dispatch(successAction(result))
    })
    .catch((error) => {
      dispatch(errorAction(error))
    })
}

ofType([ EXAMPLE_START ], mySideEffect);

which looks already much better then packing all the async logic in the action creator. Since the effect function is used only in one place we actually can take all the 3rd party services outside of the function and inject them only when we need to use the effect.

export const mySideEffect = (service) => ({ action, dispatch }) => {
  service.fetch(action.payload.url)
    .then((result) => {
      dispatch(successAction(result))
    })
    .catch((error) => {
      dispatch(errorAction(error))
    })
}

ofType([ EXAMPLE_START ], mySideEffect(mySideEffectService));

in the unit test we can use very simple mock for our service, 3rd party library or store methods like dispatch and getState.

License

ISC