DEV Community

Cover image for React Hooks - useEffect

Posted on • Updated on

React Hooks - useEffect

What is useEffect?

If you're familiar with the lifecycle methods of class based components (componentDidMount, componentDidUpdate, etc..), the useEffect hook is basically all of those methods rolled up into one convenient function. If you're not familiar with those lifecycle methods, you're very lucky 😂 😭.

useEffect is a function that you can configure to run every time a component mounts.. or unmounts.. or only on the initial render.. You can reach out to a third party API, or your own backend to retrieve data. It's very powerful. It's also not as complicated as it may seem.

How Do You Use It?


You'll start off by importing it from React. Note that we have it inside curly braces because it's a named import.

import { useEffect } from 'react';
Enter fullscreen mode Exit fullscreen mode

As stated before, it's a function. So you'll call that function.

Enter fullscreen mode Exit fullscreen mode

You'll pass an anonymous function into that function as an argument. That's the code you want to run when useEffect is called.

useEffect(() => {
    // executable code here.
    // grab data, update state, etc..
Enter fullscreen mode Exit fullscreen mode

Controlling When useEffect is Called

So we're passing a function into useEffect. As of now, that function (and useEffect itself) will be called everytime the component re-renders. If there's an input and the user is typing, that component will re-render on every keystroke.

If you're reaching out to your backend to retrieve some data, you probably don't want to do that on every keystroke.

That's where the dependency array comes in.

The Dependency Array

The function we're sending into useEffect is an argument. It can also take a second argument, which is a dependency array.

useEffect(() => {
    // this function is an argument
}, [/* this array is, too */])
Enter fullscreen mode Exit fullscreen mode

If you put a property in this array, useEffect will only be called when that property changes.

Except for the initial render. useEffect will always run at least once; on the initial render.

So let's say you have some state. We'll use a counter example. If you want useEffect to run only when that count property changes, you'll put count in the dependency array.

useEffect(() => {
}, [count])
Enter fullscreen mode Exit fullscreen mode

Now let's say you want useEffect to run on the initial render, but not on any re-render. No matter what properties change. For that, you'd pass an empty dependency array.

useEffect(() => {
}, [])
Enter fullscreen mode Exit fullscreen mode

Here, you're essentially telling useEffect to run when these properties change. Then listing no properties.

Cleaning Up

You know that function that we send into another function? Well, that function can return something...

...another function.

infinite sunglasses loop gif

Ok hear me out.

That function you can return, is a clean up function. That's where you would unsubscribe to a subscription or clear a setTimeout that you don't need anymore.

For example, if we have a setTimeout that's supposed to be called after 9 seconds, and the user is typing, (causing a bunch of re-renders), we don't want a bunch of 9 second timers going on in the background. So we'll return a function which is a clearTimeout.

useEffect(() => {
    const timer = setTimeout(() => {
    }, 9000)
    return () => {
}, [])
Enter fullscreen mode Exit fullscreen mode

Now, any time that component re-renders, (or if the user goes to a different page, and the timer isn't needed anymore), the asynchronous timeout will not be using memory in the background.


useEffect is a very powerful part of React. It may seem like a lot at first, but once you understand it and use it a couple times, it's not so bad.

I have a YouTube video with a few different examples. I also show exactly when useEffect is being called in different situations, and how to have more control over it.

Hope this helped somebody and thank you for reading!


Top comments (0)