Hooks have grown into a fundamental part of building React apps since their introduction in late 2018.
Aside from the fundamental React hooks like useState
and useEffect
, the speed and convenience that hooks like useSWR, useQueryParams, and useLocalStorage bring to app development is hard to give up once you’ve had a taste.
If you’re working on an older React project that still uses some (or many) class-based components, chances are you’ve skipped over using a neat third-party hook because it was too much of a hassle to use it with class components.
To use that fancy new hook in your class component, you have a few options:
🐸 Rewrite your class component as a function component
If your component is small enough, it might be wise to simply refactor it as a functional component and save yourself a good deal of pain down the road.
Here’s a great guide to doing just that
But of course, this doesn’t work for everyone.
🎁 Wrap a hook in a Higher-Order Component
If all you need is a one-off solution and it isn’t worth refactoring your entire component, you can create a higher-order component (HOC) wrapper for the specific hook you want to use.
⚠️ This approach involves creating a separate HOC wrapper for each hook that you want to use in a class component. If this works for you, great! Otherwise, the next method might be a better alternative.
This will work differently depending on whether your hook expects any parameters.
Hook without parameters
Consider the following hook that doesn’t expect any parameters:
You can create a Higher-Order Component wrapper around the hook that looks something like:
Note that the
Subtract
type used here comes from the excellentutility-types
package.
And then use it inside any of your class components:
Hook with parameters
If your hook does require some parameters, creating the wrapper is a more involved but still perfectly doable:
✨ Turn any hook into a Higher-Order Component
We can go a step further by generalising the HOC wrapper approach to any hook that takes no parameters.
If your hook takes any parameters, this code won’t play well with TypeScript. Check out
hocify
if you don’t care too much about satisfying the type checker.
You can use this function to create a HOC, and then use that HOC to wrap your component:
💡 Next steps
The generalized approach works pretty well for hooks that don’t have any parameters, but extending it to hooks with parameters turned out to be a bigger challenge than I had the time for.
It’s easy enough to implement in JavaScript, but typing the function - generics and all - is a lot trickier.
Further Reading
React Higher-Order Components in TypeScript: This article does a great job of explaining the various kinds of HOCs and the TypeScripts subtleties that go along with them.
hocify if you just want to use hooks in your class components without worrying too much about perfect TypeScript compatibility.