How Locus uses React Hooks with Class components
By: Govind Sharma
Tags: Web Development, Front End Development, React, Coding, React Hook

If you are a long-time React developer, you might be familiar with the times before Hooks when all stateful logic had to reside in class components, and functional components could only be presentational. Class components helped developers write stateful frontend code in a declarative way. For a long time, frontend developers were happy with using classes as the default component authoring experience.

However as the complexity of web apps grew, various inconveniences with class-based components began cropping up. Most business logic had to be split between lifecycle methods, affecting readability and code reuse. Complex patterns like render props and higher order components (HOCs) had to be used to reuse logic between components.

To help with all these issues and with the aim of making authoring React components easier, React Team introduced the concept of Hooks. Hearing about Hooks and reading the documentation for the first time, it felt like magic — these were functional components that could do everything that class components did! No more worrying about lifecycle methods and no dealing with complex class syntax either.

With Hooks, the reusability of complex logic also drastically improved as we could now use features like state and lifecycle methods directly in a function. This makes util functions much more powerful as the logic they can implement can be totally generic.

Not only this, various Hook functions can be combined into more powerful ones. Called Custom Hooks, such functions can further be combined into even more powerful functions. There’s literally no limit! Believe me, after you start using Hooks, you’ll wonder how you were ever able to code and live, without them.

The problem with using Hooks in class components

Considering all these advantages of Hooks, there are still some challenges to using Hooks in a legacy codebase. The most common being when you want to use some Hook logic in your project that is mostly class-based, and it’s not an option to rewrite those class components to Hooks at the moment.

As can be seen from the official React Hooks documentation, Hooks are a new core concept in React, and they don’t work inside classes. And rewriting your existing components to use hooks is not always the most preferred approach.

In such cases, refactoring the component is not always a feasible approach due to a variety of reasons. Existing components can just be too complex, or it could break many other things across the project if you change it. It is also questionable to refactor existing components without a comprehensive refactoring strategy.

That leaves us needing to find a way that allows us to use a Custom Hook with a class component. At Locus, we also faced this problem. We have a large class-based codebase, and trying to use the new Hooks-based logic in existing components was a challenge. However, the below-mentioned patterns have helped us overcome this limitation.

Patterns to use Hooks in class components

To understand how we can use Hook logic inside a class component, let’s take a look at an example custom hook `useWindowSize`. As the name suggests, this hook keeps track of the window dimensions which allows us to use window size-based logic in our components. Let’s take a look at the code.

This Hook keeps track of the window dimensions in a state object using the `useState` React Hook, which allows us to use state in functional components. Then it uses `useEffect` to set up the event listener on the window resize event on mount, and remove the listener on unmount. The resize event handler updates the window dimensions state by using the state updater function returned by `useState`.

I am not going into the details of how `useState` and `useEffect` Hooks work in this blog, but you can check out the official React Hooks documentation. Also, Dan Abramov wrote a nice article about `useEffect` that you should check out for more information.

Using Hook as HOC

Higher Order Component (HOC) is an advanced React technique for reusing component logic, and this concept gives us the ability to use Hook logic inside our existing class components. The idea is to get a component as an input and return that same component with some additional props. In our case, we will pass the results of our Hook function as a prop to the input component.

The final step is to simply wrap our existing class component with that HOC. And then, we simply use `windowHeight`, `windowWidth` props as any other prop passed to the component.

Using Hook as render prop

Another pattern to use Hooks with class components is to use the render prop pattern. In this, we use a function component that renders its children with the results of the Hook functions.

The next step here would be to import this function component into your existing class and pass down the class’s children as render prop to it.

Automate Hooks to HOC conversion

In a large codebase, doing this hooks to HOC conversion every time you need to use a hook logic into an existing class component can be time-consuming and error-prone. To help with this, this brilliant little library can automatically generate a HOC from your Custom Hooks.

Conclusion

Using Hooks is a powerful new concept in React and helps improve the overall developer experience of working with React. However, being a new core concept, they can’t be used inside class components. This can be challenging for teams with existing class-based codebases. Trying to use the new Hooks-based logic in existing components is a challenge. However, these two patterns have helped us avoid unnecessary refactoring of existing code, just to be able to use React Hooks. This has helped the Locus frontend team to be more productive while using the latest React pattern along with our existing codebase.

Hopefully, these patterns will help you to efficiently use React Hooks in your codebase too. Thanks for reading and happy coding!