Peter Etherington, Front End Developer
November 28, 2018
If you’re developing in React, you may have some reservations about Hooks (I do too). But if you’re not familiar with them yet, here’s what you need to know:
With ReactConf 2018 behind us, there’s plenty of buzz about React’s transformative new feature called “Hooks”. Dan Abramov and Ryan Florence each gave their own demos showcasing the useState and useEffect Hooks to much applause, along with a few others. The big takeaway here is Hooks are going to drastically reduce the amount of code needed to achieve functionality that involves state, lifecycle, context, and refs. But also, it’s going to make extracting and reusing stateful logic in other components a whole lot easier.
Another important piece to this announcement is: Hooks are optional. Hooks have been released to the public in React v16.7.0-alpha and are being discussed in an open RFC on GitHub. They’re an additive, non-breaking feature that exists solely for those that choose to use them. Meaning, there’s no refactoring required - unless you feel compelled to do so. Teams can continue to push out updates and releases as scheduled and begin using Hooks when they’re ready.
The first thing that struck me about Hooks is that they seem to do a lot “behind the curtains”, which could make debugging more difficult in unpredictable ways. Hooks could also impede newer developers from fully grasping what the code they write is doing, specifically how the lifecycle of a component works. Of course, it’s extremely early for Hooks. When you consider that these potential pitfalls, among others, are already being discussed in the RFC and this new feature is 100% optional, it’s hard not to get even a little excited about Hooks.
In the following example, we will explore a basic implementation of useState and useEffect in our own custom hook that I’ve called useWindowData. But first, there’s two rules you need to remember:
Hooks need to be used at the top level and from inside React function components. With that in mind, we’ll start by using array destructuring to declare two variables, assign them to the useState hook and pass the initial state as the argument. The initial state can be an object, array, or even a primitive - like a string or number. I’ve labeled the first variable value – this will represent the current state - and I’ve labeled the second setValue – this is the method used to update value. Our custom hook is going to return the current window width on page load and when we adjust the browser window.
The next step is to define a function variable that we can pass to a resize event to update our state. Once this is done, we introduce useEffect – which is used to perform side effects in function components. Think of this hook anytime you want to do something with your component after render. We’re using it here to manage the process of attaching the resize event listener. The return value of this hook will detach the listener when the process is finished and prevent our subscription to the window resize event from causing a memory leak. React performs this ‘clean up’ when the component unmounts. You’ve probably noticed that this means we don’t need lifecycle methods like componentDidMount and componentWillUnmount. Lastly, we return the window width and slap together some JSX to display what we’ve done on the page.
And there you have it. We were able to accomplish all of this in 30 lines of code compared to 41 lines (27% more code) without Hooks! That may not seem like a lot in this small example but when you consider project budgets with hundreds or thousands of hours, I’m sure you can imagine that Hooks are going to save everyone a lot of time. Hopefully, from this pilot study you’ve been able to get a sense of how Hooks can help React developers build web applications by reducing the size of components while also increasing our freedom to abstract stateful logic into reusable functions. Plus, with Hooks there will be a lot less having to bind this in the constructor (cue raucous applause!).