How to Start with React Hooks

Alexandre Jamarco
The Startup
Published in
6 min readApr 16, 2020
No. Not this Hook we are going to talk about! Source.

If you are a beginner in React and are using classes all-around in your code you probably had noticed that sometimes it is not easy to keep track of your states, how to update them, how to render them, etc. For me, particularly, I was overwhelmed by the 'this' word.

'this' here, 'this' there… It wasn't a very pleasant experience. But no worries. Hooks to the rescue!

In this post, I'll explain why Hooks is so much easy to understand and how it can make your code more readable than it was before. I'm also going to introduce you with a few basic examples using some of the new features provided (using useEffect and useState).

What is Hooks?

Accordingly to the React Documentation:

Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.

Hooks was a new addition in React 16.8. React Native supports Hooks since the 0.59 release.

Basically, using functions instead of classes can have a positive impact on the performance and the readability of the code. And we are going to see why.

Classes will come to an end in React?

No, React has no intention of getting rid of classes. Hooks can be used concurrently with Classes and will not interfere in the way you write your code. However, Hooks doesn't work inside classes.

The idea is that developers do a gradual change, introducing functional components as new code is created.

What exactly is a 'hook'?

Before dive into some examples, it is important to explain this concept first. A hook is a function that can let you inside a React state and lifecycle features (accordingly to the React Documentation, a hook let you 'hook into' a React state).

If you worked with a function in React before, sometimes you had the need to add some state to it. Before Hooks, you had to convert this function to a class (enabling you to use State and setState()). With Hooks you can achieve the same result in a functional component.

Rules for a Hooks

Apart from all rules that Hooks has to follow (since it's a Javascript function), we also have some additional guidelines to follow:

  • Only Call Hooks at the Top Level: You cannot call Hooks inside loops, conditionals, and nested functions. You should call it at the top level of your React function. This allows React to call it in the same order every render.
  • Do not call Hooks from a regular Javascript function. Always use a react function component or from a custom Hooks.

Some Code Examples Using Hooks

Now I will show some basic examples that could be useful to you, and also show the power of Hooks. I took these examples from the Hooks documentation (link at the bottom of the post).

The first hook we are going to learn is the useState().

useState()

Let say you have a class like this one:

Basic React class.

Basically, this class has a state (with a value ‘count’, started with 0). Every time we click in a button inside the form we should add 1 to this value (using setState on line 16).

Using the same example, but using Hooks instead:

Same example as above, but using a functional component.

Here we’ve imported ‘useState’ from React on line1. The most important thing in this code is at line 4.

useState() declares a ‘state variable’. It’s a way to preserve a value between function calls. Normally, variables “disappear” when the function exits but state variables are preserved by React.

The only argument that useState() has is the initial value of count. Unlike classes, the ‘state’ here doesn’t have to be an object. We can call as my useState as we like.

At the end, useState() returns a pair of values: the current state and a function used to update this value. So, instead of use this.setState and this.state.count we can set up a new value using the function setCount and adding 1 to the curent count value (line 9).

Finally, it is so much easier to read:

<p>You clicked {count} times</p>

Than:

<p>You clicked {this.state.count} times</p>

useEffect()

The Effect Hook lets you perform side effects in a functional component.

Following the previous example, we can add a new code to it:

Adding useEffect to our code example

On the first line we added a new function to import: useEffect. We make use of this function on line 6. useEffect acts similarly to the methods componentDidMount(), componentDidUpdate(), and componentWillUnmount() in classes.

Just to be clear, some examples of side effects in React are Data fetching, setting up a subscription and manually changing the DOM in React components. A side effect in React can or cannot require cleanup.

Some effects that don’t require clean up: Network requests, manual DOM mutations, and logging. We run the code that performs this action and forget about them.

For this one, we only use:

useEffect(() => {   document.title = `You clicked ${count} times`;});

By default, this code will run both after the first render and after every update. So, for every render, we are updating the title of the page with the phrase (alongside with the value ‘count’).

Although this is very similar to componentDidMount or componentDidUpdate, effects scheduled with useEffect don’t block the browser from updating the screen. This makes your app feel more responsive. When you need your effect to happen synchronously, there is the useLayoutEffect Hook, with an API identical to useEffect.

You can ask ‘Ok, but I want to run this effect only when the component is mounted, not on every update’. Of course, you can do that.

The most common way to run something just when the component is rendered for the first time is using an empty array ( [ ] ) as a second argument for the useEffect call.

Running useEffect just when the component is mounted

However, this approach is considered unsafe by React and it also provides better solutions for this case.

You can also specify a useState variable to be watched by effect. This way the useEffect hook will only run if this variable changes.

Setting a condition for the useEffect hook to run

In the picture above, useEffect will only run if ‘count’ changes, no matter how many times ‘value’ has changed.

Effects that require cleanup

A very good example of effects that need cleanup when unmounting: we might want to set up a subscription to some external data source. In that case, it is important to clean up so that we don’t introduce a memory leak.

Let say we have a class component for a live chat API:

Example of a class component

Here, we have on componentWillUnmount() a method call to unsubscribe from somewhere. This will have to happen once the component is unmounted only. We can achieve the same result with the return value of the useEffect hook:

Do the cleanup after the component is unmounted

As we can see on line 14, we have a return value for our useEffect() hook. This callback will run as soon as the component is unmounted, enabling us to cancel the subscription (the same way we did using componentWillUnmount).

--

--

Alexandre Jamarco
The Startup

Brazilian, Software Engineer, living in Sheffield, UK