codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

Follow publication

Redux with React Hooks

React has introduced the concept of Hooks in 16.8 evolving the way we’ve been writing React Components using Classes in order to tap into the lifecycle methods. With hooks api, as the name suggests, React encourages us to write the components in a functional manner while gaining access or hooking into the lifecycle methods through the said hooks in a given component. And, after using it for a while, I see the point why React favours functional components using hooks api because of the brevity and cleanliness it offer compared to a verbose class based component. Not only this, in order to attach some logic, we had to rely upon patterns like render props or higher order components which basically re-structured our components by adding unnecessary level of dom hierarchies for each HOC or render prop element also known as “wrapper hell” of components surrounded by layers of providers, consumers, higher-order components, render props, and other abstractions.

Wrapper hell of React HoCs

If you’ve worked with Angular (any version), you must be familiar with the concept of Angular Directives which in simple words is a way to add super powers to a DOM element

<p appHighlight>Highlight me!</p>

For eg: appHighlight here is an attribute directive which when applied to any element would augment its behaviour by say adding some event listener to it and reacting by changing some visual css properties as in this example. This attribute directive can be applied to any element and it will add the required behaviour it. Hence, this reusable logic can be kept at one place in a directive.

Similar sort of thing was introduced in React as well termed as Mixins but it couldn’t work out well in favour of ES6 classes. React hooks are said to be Mixins Done Right!

This article is not going to be a react hooks tutorial, there are plenty out there already. Rather, we’d be discussing about a problem that I encountered using Centralised state pattern as Redux with React hooks.

Motivation

React hooks api has an enforcement of only being used inside functional components. Class based components can’t use React hooks. And this means that, we can no more use our favourite connect HOC function to wrap our class component before exporting it.

export default connect(mapStateToProps, mapDispatchToProps)(myComp);

Since, HOCs here introduces hierarchies into the dom structure, which defeats the whole ideology for hooks based functional react components. React hooks provide a way of maintaining a local state inside the components very well with the built-in useState effect.

useState hook example

It has its own advantages for sure, which you can read here from the official docs. There’s another effect called useReducer which again is nothing but a little abstraction on the useState effect.

useReducer React Effect example

The state would be local to the component itself. While, it works for smaller apps but for practical large applications, the concept of Centralised State Management has worked quite well over the years. A single central state as a source of truth makes it easier to reason about the changes happening in the application through formatted data structures called as Actions. We won’t go over the philosophy of Redux here.

The job we’re trying to accomplish is create a useRedux sort of a hook, that returns us the mapped props just like the connect HOC.

useRedux Hook

Pretty much like connect HOC, except that, it doesn’t take the React Component Class as an input and returns another nested component by adding props to it. Rather, it’s a classic function, that takes in the mapping functions and simply return the mapped props.

Delving more into how connect HOC works. It’s provided by the react-redux package. At the root level of our app, we wrap whole application with <Provider /> as

React Redux example

This is the usage of React Context API. We need to grab the reference of our single Redux store everywhere throughout our application. Hence, we need to specify the reference of it once at the root level of our app and without passing it as a prop to any of the children component, we can use it in any level of nested components as

Consuming react-redux context in a deep nested component

connect function uses the same thing by wrapping the React component into the Consumer end of the React context and grab the reference of the state from there.

A contrived version of the connect function looks something like this

A contrived implementation of react-redux connect function

Notice how at line 5, the context value of store which was passed to the Provider at the root level is being accessed. Further, getState() method is being called on this store and mappedProps are being prepared.

Same approach we’re gonna use but with a twist of useContext hook.

useRedux hook usage

Here, we’re maintaining a reference to the context variable created as

const context = React.createContext(null);

and since we have passed a reference to the redux store as a value to the context <Provider value={store} />, we can grab it for consumption by simply using the useContext hook.

By destructuring store, we get access to getState and dispatch methods of redux store. Using getState, we can get the current state and hence create mapped state out of it by passing it to our said mappedStateToProps and mappedDispatchToProps functions.

Not only this, we also need to listen to any future changes in the redux store in order to re-render our component in which our useRedux hook is “hooked”. Hence, inside useEffect, we need to subscribe to the redux store once and call setState by checking if the props have changed which in turn triggers a render.

That’s about it. The usage looks like this

Sweet. We’re able to hook redux into our functional components without wrapping them unnecessarily into HOCs.

You can use this hook easily from npm as

npm i -S @mollycule/redux-hook

The complete docs are available here.

NPM package for useRedux Hook

Thanks :)

References

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

Written by Param Singh

Senior Front-end Engineer at AWS, Ex-Revolut, Flipkart. JS enthusiast. Cynophile. Environmentalist

No responses yet

Write a response