Implementing useDispatch hook without installing alpha versions of Redux

Categories React Hooks
Photo by Nick Fewings

This article might be useful to you if you need to dispatch Redux actions from your custom hooks. Unfortunately currently Redux’s useDispatch is in alpha and this is not a good idea to use alpha version of the library in the production.

First, we need to create a context as we need to be able to access useDispatch in any hook used in the app:

const ReduxDispatchContext = React.createContext(null)

Second, we need to create a provider:

const DispatchProvider = connect(
  null,
  (dispatch) => ({
    dispatch,
  }),
)(({dispatch, ...rest}) => {
  return <ReduxDispatchContext.Provider {...rest} value={dispatch} />
})

This provider does a few important things. 1) It connects to the Redux and this way gets access to its dispatch function. Note that mapStateToProps is null to ensure that Redux does not re-render DispatchProvider in response to some changes in the store. 2) It renders ReduxDispatchContext provider and its value is dispatch function. Note that context provider will re-render its consumers every time the value changes but dispatch never changes, therefore, using providers of ReduxDispatchContext is safe from the performence standpoint.

Finally, we create useDispatch custom hook which utilizes useContext hook from React:

function useDispatch() {
  return React.useContext(ReduxDispatchContext)
}

useContext returns the value which was provided to the provider. In our case, this value is dispatch function from Redux.

Let’s put all the functions created above to a separate module:

import React from 'react'
import {connect} from 'react-redux'

 const ReduxDispatchContext = React.createContext(null)

 function useDispatch() {
  return React.useContext(ReduxDispatchContext)
}

 const DispatchProvider = connect(
  null,
  (dispatch) => ({
    dispatch,
  }),
)(({dispatch, ...rest}: any) => {
  return <ReduxDispatchContext.Provider {...rest} value={dispatch} />
})

 export {useDispatch, DispatchProvider}

Now, if you have some custom hook that for example needs to dispatch a notification while notifications are managed by Redux you have to do 2 steps:

First, wrap your app with DispatchProvider, but it itself must be wrapped by Redux provider otherwise it would not get access to dispatch.

Second, use the dispatch fucntion in your custom hook:

...
const dispatch = useDispatch();
...
dispatch(addNotification('success', 'My custom hook notifies Redux!'));
...
FacebooktwitterlinkedinFacebooktwitterlinkedin

Leave a Reply

Your email address will not be published.