Note: Reading time for this post is approximately 15 minutes. This post assumes you are familiar with React concepts such as Function & Class Components, HOC, Hooks, etc and also with using Redux Store for State Management in React. If you want to learn or refresh these concepts, head over to the below links.
- https://reactjs.org/docs/components-and-props.html
- https://reactjs.org/docs/hooks-intro.html
- https://reactjs.org/docs/higher-order-components.html
Introduction
React introduced Hooks for abstracting stateful logic between components and it changed the way we write code in React. We could now use state, lifecycles and almost any other React feature inside functional components which made things a lot simpler and code much cleaner. As we are aware, Higher-Order Component (HOC) played a major role in reusing stateful logic before Hooks were introduced. HOC’s are a bit tedious to use and make code more complex. Hence, the focus has since then shifted to Hooks.
The most popular example of HOC which I can think of is the connect() HOC from Redux. It helps us in connecting our component to the Redux Store in React. We need to wrap the component that needs to access the store in the connect() HOC. Additionally, we can pass in two parameters:
- mapStateToProps - Useful for subscribing to the values from the store by extracting them as props.
- mapDispatchToprops - It binds action creators to dispatch and automatically dispatches the actions upon being called.
Redux Hooks
Taking advantage of the Hooks pattern, Redux has officially released Redux Hooks as an alternative to wrapping components in the connect() HOC for subscribing to the store. Redux Hooks are available from the react-redux version 7.1.0.
Lately, there has been a lot of discussion over whether React Hooks have eliminated the need for using Redux. This discussion mostly arises because it's a little complicated to connect React components to the Redux Store using HOC (at least that's what a lot of us feel). Redux Hooks make this comparison (of managing the state with or without Redux) Apples to Apples.
To understand how Redux Hooks eliminate the need of connect() HOC, let’s quickly have a look at an example which uses connect() HOC for subscribing to the Redux Store:
Here, we have a component called RecentActivity which as per its description displays the recent games played by a particular user.
- The RecentActivity component is wrapped inside the connect() HOC
- The mapDispatchToProps injects the action ‘loadActivity’
- The action ‘loadActivity’ is dispatched from the componentDidMount() lifecycle to fetch and save the user’s recent activity in the redux store
- The mapStateToProps subscribes to the user’s activity and name from the store
- The activity prop is then used to display the recent games played by the user
Now, Let’s us see how Redux Hooks help us make the same code simpler and cleaner. There are three Redux hooks which we need to understand:
- useDispatch() - It returns a reference to the dispatch function from the Redux Store which can then be used to dispatch actions in the component whenever required.
- useSelector() - It is used to subscribe to the required data from the Redux Store using a selector function. The selector function here takes the store as its only argument and extracts the required data as props. The selector will be called whenever the component renders and also whenever any action is dispatched. When an action is dispatched, useSelector() will do a reference comparison of the previous selector result value and the current result value. If they are different, the component will be forced to re-render.
- useStore() - It returns the Redux Store which we had created earlier and passed in the <Provider> component.
Enough with the theory, let’s dive straight into the code:
We have now got rid of the connect() HOC along with mapStateToProps and mapDispatchToProps. This code looks a lot more simple and cleaner already. Observe how easy it is to subscribe to the store and dispatch actions using these Hooks.
useSelector() is conceptually similar to mapStateToProps. We subscribe to ‘activity’ and 'name' data from the store using this hook.
useDispatch() helps in getting rid of mapDispatchToProps. In the above example, we create a dispatch object initially and then use it to dispatch actions throughout the component.
There is also a useState() hook which is not very frequently used. useSelector() is the preferred way of subscribing to the data from the store. However, this may be useful for less common scenarios that do require access to the store.
To explore and learn more about Redux Hooks you may find these links useful:
Top comments (1)
Nice one, I would like to see how you can use redux-hooks for authentication.