Debugging Microservices & Distributed Systems
4 min read

Demystifying React Hooks

Hooks can save you time and improve the quality of your code

You’ve probably heard about React’s exciting feature: Hooks. Introduced in React version 16.8, Hooks allow us to write stateful components without using the class syntax.

If you want to learn more about Hooks, this guide will provide a gentle introduction.

Why Use Hooks?

Before Hooks, reusing state, logic, and functionality between class components was challenging. You often had to pass props down multiple levels or use render props, leading to problems like:

  • Large Components: Components became bloated with code.
  • Duplicated Code: Repeated code across different components.
  • Complex Patterns: Solutions like higher-order components (HOCs) were required, adding complexity.

Hooks apply the React philosophy of explicit data flow and composition within a component, rather than just between components.

Refactoring a React Component from Class to Hooks

Hooks are still relatively new, and no one expects you to refactor your entire app to use only Hooks. However, it’s worth trying them out to see how they can improve the structure and quality of your codebase.

Let’s start with a simple React class component.

import React, { Component } from "react";
class Search extends Component {
state = {
searchFieldValue: ""
};
handleSearchFieldChange = e => {
e.preventDefault();
this.setState({
searchFieldValue: e.target.value
});
};
render() {
const { searchFieldValue } = this.state;
return (
<input
onChange={this.handleSearchFieldChange}
type="text"
name="search"
placeholder="search"
value={searchFieldValue}
/>
);
}
}
export default Search;

This component has three responsibilities:

  1. Saving the search state
  2. Changing the search state
  3. Rendering the search UI

While the component is functional, there’s always room for improvement. So, how can we make it better using Hooks?

Hooks to the Rescue

Now, let’s refactor the same class component using Hooks. We won’t change any functionality, but we will simplify the code.

import React, { useState } from "react";
const SearchWithHooks = () => {
const [searchFieldValue, handleSearchFieldChange] = useState("");
return (
<input
onChange={e => handleSearchFieldChange(e.target.value)}
type="text"
name="search"
placeholder="search with hooks"
value={searchFieldValue}
/>
);
};
export default SearchWithHooks;

By using Hooks, we’ve reduced our code from 29 lines to just 17. That’s a 41.3% decrease in code, which translates to less to write, less to debug, and less to maintain.

Imagine saving that much time for every component in your app! While it might be overly optimistic to think you can cut your development time in half, the potential for significant time savings is real.

Let’s break down how Hooks work:
  1. Importing Hooks: Start by importing useState from the React package.
import React, { useState } from 'react';
  1. Defining State: Defining state with Hooks looks like this:
const [searchFieldValue, setSearchFieldValue] = useState('');
  1. searchFieldValue is the initial state.
  2. setSearchFieldValue is a function that allows us to update the state.

The array brackets might look unfamiliar at first. This syntax is called array destructuring assignment. It allows us to unpack values from arrays (or properties from objects) into distinct variables.

let x = [1, 2, 3, 4, 5];
let [y, z] = x;
console.log(y); // 1
console.log(z); // 2

And that’s it! We’re no longer required to use class-based syntax for stateful components.

Here’s how you would create the search component with React Hooks:

const SearchComponent = () => {
const [searchFieldValue, setSearchFieldValue] = useState('');
const handleSearchChange = (event) => {
setSearchFieldValue(event.target.value);
};
return (
<input
type="text"
value={searchFieldValue}
onChange={handleSearchChange}
/>
);
};
Should I Use Hooks, Classes, or a Mix of Both?

The official React documentation offers good advice on this topic:

“When you’re ready, start trying Hooks in new components you write. Make sure your team is on board and familiar with Hooks. Rewriting your existing classes to Hooks is not recommended unless you planned to rewrite them anyway (e.g., to fix bugs).”

Here’s an example of a simple toggle component using Hooks:

const ToggleComponent = () => {
const [isToggled, setIsToggled] = useState(false);
return (
<label>
<input
type="checkbox"
checked={isToggled}
onChange={() => setIsToggled(!isToggled)}
/>
{isToggled ? 'ON' : 'OFF'}
</label>
);
};

Notice that you can pass any value or type to useState()—in this case, we’re using a boolean. You could also pass an object, array, or number, just as you would with setState({}).

Start small by creating a few components with Hooks, and see how they fit into your development workflow.


Related Articles

If you enjoyed this article, you might find these related pieces interesting as well.

Recommended Engineering Resources

Here are engineering resources I've personally vetted and use. They focus on skills you'll actually need to build and scale real projects - the kind of experience that gets you hired or promoted.

Imagine where you would be in two years if you actually took the time to learn every day. A little effort consistently adds up, shaping your skills, opening doors, and building the career you envision. Start now, and future you will thank you.


This article was originally published on https://www.trevorlasn.com/blog/demystifying-react-hooks. It was written by a human and polished using grammar tools for clarity.

Interested in a partnership? Shoot me an email at hi [at] trevorlasn.com with all relevant information.