Hooked on React

An Introduction to Functional Hooks Components (useState & useEffect)

(banana for aesthetic)

There is a trending movement away from object oriented programming and towards functional programming on the front end, and we have Hooks to thank.

What are Hooks?

Hooks allow you to use state and other React features without writing a class.

Why?

Hooks provide more flexibility around implementing lifecycle methods. The lifecycle methods in a functional Hooks component (unlike those in a class component) allow you to decide how tightly or loosely coupled the methods are.

Hooks are 100% backwards-compatible, meaning they don’t contain any breaking changes.

Hooks allow you to reuse stateful logic without changing your component hierarchy. You can extract stateful logic from one component and share it across many components, which makes life much simpler when building store apps and many others.

Complex components like componentDidMount, componentDidUpdate, and componentWillUnmount can become overly complex when you have certain data changing together and/or not splitting apart together. Hooks let you split one component into smaller functions based on which pieces are related (for example: a subscription or fetching data), rather than forcing a split based on lifecycle methods.

And finally, simply letting go of classes in favor of using only functional components simplifies using React.

Two of the most useful Hooks are useState and useEffect. Below is a basic introduction on how to use them.

useState()

You can think of this method as kind of like a combination of the class methods setState and constructor. Basically, it declares a ‘state variable’. The basic syntax is as follows:

On the left side of the equation we have a destructured array: the current state value and the function that updates it. This is the return value of useState(). On the right side, we pass one argument to useState: the initial or default state. Remember that this is inside a functional component, so the state will be local. Unlike with class components, the state Hook doesn’t need to be an object. The value can be any type of your choosing: a boolean, an object, an array, a string, etc. If you want to have multiple values in state you can call useState in the same component as many times as you like. This is very handy when you require state variables of different types. Let’s look at some examples.

First, make sure to import the Hook from React. Then declare your variable. In this example our state is called count, and the function that modifies it is setCount. We pass an initial value of 0 to the Hook itself. In other words, we are setting the default value of count to 0. In our return statement we’re rendering a button with onClick an event listener that calls setCount. We pass in the new value, or in this case the logic that returns the new value. React will then re-render the Example component, passing it the new count value — 1. Since we aren’t getting passed state through props, we don’t need to call this.props.count when we want to render it to the DOM. We can just simplify things to {count}. Let’s add multiple variables!

Another special feature of this Hook (sometimes called the “State Hook”) is that the variable doesn’t disappear when the function exits. React will remember its current value between re-renders, and provide the most current one to our function. The state is ‘created’ only the first time it renders, and after that we are provided with the current state during the next renders.

useEffect()

The “Effect Hook” allows you to perform side effects in function components. You can think of it as a combination of componentDidMount + componentDidUpdate +componentWillUnmount all rolled into one. What’s a side effect? Sometimes just called effects, examples of these are: data fetching, logging in, setting up a subscription, or manually changing the DOM.

Using this Hook tells React your component needs to do something after render. Sometimes we want a function to run after every render, but with class components we only have options like componentDidMount or componentDidUpdate. We’d have to repeat code in order to have the same effect run after every render. The Effect Hook takes care of this:

Building on our example from earlier, we use useState() to declare state variables, count and fruit. Then we tell React we want to use an effect. We pass a callback function to useEffect() that will set the document title with an interpolation of our state variable. This callback is the effect. The function will be read asynchronously and run after the DOM is updated, for every render. Because the effect is run after every render, each effect “belongs” to a render, and thus guards against the data becoming stale.

There is one small but mighty piece of syntax you must know when using the Effect Hook. Observe these two examples:

Those two square brackets at the end of the second example make all the difference. It’s actually an empty array, an optional second argument for useEffect. The hook will look at the values in the array and compare them to the previous values of whatever is within the scope of the hook. If the values changed, the effect will run. If not, nothing happens. By passing an array with no values to the hook as the second argument, we guarantee that there is nothing to create a comparison with, and therefore, the effect will only run just the once, upon component render. Using this syntax, useEffect is comparable to componentDidMount. The first example will continually run and check, more similar to componentWillUpdate and/or componentDidUpdate.

Perhaps the greatest benefit of the Effect Hook is that it replaces the separation of componentDidMount and componentWillUnmount. When you have an effect that requires a cleanup, with class components you need both aforementioned functions. useEffect() seamlessly blends them into one function that handles cleanup by itself. Checkout this example to see examples and a thorough explanation.

When you start to implement Hooks, remember these two rules:

  1. Only call Hooks at the top level (don’t call Hooks inside loops, conditions, or nested functions)
  2. Only call Hooks in React functions (not vanilla javascript)

If you want to learn more about Hooks, check out these resources:

Software Engineering student at Flatiron School

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store