DEV Community

Cover image for Get Up And Running With The useEffect Hook.
Talabi Ayomide
Talabi Ayomide

Posted on • Updated on

Get Up And Running With The useEffect Hook.

Hooks are new features incorporated into React 16.8. and the newer versions. They basically help you use React features without writing a class.

In this guide, we are going to cover why this hook exists and how to use it in React.

If you started your React journey before version 16.8, then you have to unlearn lifecycle methods and instead think in effects.

The useEffect hook lets us express different kinds of side effects after a component renders. In case you are wondering what side effects are, relax, you will understand in a second.

Side effects are unpredictable actions performed with the "outside world." Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects. Regardless of knowing what this term means, you have most likely used it.

There are two common kinds of side effects in React components: those that don’t require cleanup, and those that do.

Side Effects Without Cleanup
Network requests, manual DOM mutations, and logging are common examples of effects that don’t require a cleanup. We can run them and immediately forget about them.

Side Effect With Cleanup
Some effects require cleanup to reduce memory leaks.
Timeouts, subscriptions, event listeners, and other effects that are no longer needed should be disposed.
This is done by including a return function at the end of the useEffect Hook.

cleanup

useEffect is a tool that lets us interact with the external world but does not affect the rendering or performance of the component that it's in. React enables multiple useEffect instances inside a React functional component. The code can be broken down into multiple Hooks containing logically related code in a single function.

By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates.

It is a combination of componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods in class-based components.

Why useEffect is defined inside a component?

“useEffect” function is defined inside the component so that the variables and the functions defined inside the components can be accessed directly. If you are familiar with closures in JavaScript, you will probably be having an "aha!" moment now. And if you don't, it is not a problem.

Closures are functions that are nested in other functions and simply allows variables outside of the scope of a function to be accessed. It takes advantage of the concept of Closure to provide access to the local functions and variables defined inside a function.

How to use the useEffect hook

  1. We import useEffect from "react"
  2. We call it above the returned JSX in our component
  3. We pass it two arguments: a function and an array
import { useState, useEffect } from "react";

function Counter() {
  const [count, setCount] = useState(0);
  const [calculation, setCalculation] = useState(0);

  useEffect(() => {
    setCalculation(() => count * 2);
    console.log(calculation);
  }, [count]); // <- add the count variable here

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
      <p>Calculation: {calculation}</p>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

The function passed to useEffect is a callback function which will be called after the component DOM renders. The side Effects are performed inside this function.

The second argument is an array, called the dependencies array. This array includes all of the values the side effect relies on. What this array will do is it will check and see if a value has changed between renders. If so, it will execute our use effect function again. We can optionally pass dependencies to useEffect in this array.

1. No dependency passed:
useEffect(() => {
//Runs on every render
});

2. An empty array:
useEffect(() => {
//Runs only on the first render
}, []);

3. State values passed into array:
useEffect(() => {
//Runs on the first render
//And any time any dependency value changes
}, [state]);

Summary

useEffect is a tool that lets us interact with the external world but does not affect the rendering or performance of the component that it's in.
By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed, and call it later after performing the DOM updates.

It is a combination of componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods in class-based components.
We pass two arguments: a function and an array into a useEffect hook.

Discussion (12)

Collapse
peerreynders profile image
peerreynders • Edited on

Please have a look over the updated documentation:

Collapse
ayo_dev profile image
Talabi Ayomide Author

Thank you!

Collapse
crowdozer profile image
crowdozer

For those just getting started with useEffect, I highly suggest using something that provides intellisense about the hook's dependency array.

It's straightforward once you're used to the concept, but in the beginning, it will save you lots of headaches.

Collapse
christiankozalla profile image
Christian Kozalla

Nice article, I like it :D

Collapse
ayo_dev profile image
Talabi Ayomide Author

I'm glad you found it useful.

Collapse
christiankozalla profile image
Christian Kozalla

I've recently written a post about useEffect, specifically about the dependency array. Because I tend to forget how to use it right. You find it here if you like: chrisko.io/posts/useEffect-hook-de...

Thread Thread
ayo_dev profile image
Talabi Ayomide Author

It was an amazing read..

Collapse
himanshupal0001 profile image
Himanshupal0001

Thanks for the explanation. But I still struggling to understand this concept. Can you explain it with a more practical app or example. Please share if you have any YT link etc.

Collapse
ayo_dev profile image
Talabi Ayomide Author

I think this Youtube video by WebDevSimplified will help you get a clearer picture.
youtu.be/0ZJgIjIuY7U

Collapse
lukeshiru profile image
Luke Shiru

Worth noting that the example you provided is not ideal to showcase useEffect, because that same "problem" can be solved without it:

import { useState } from "react";

const Counter = () => {
    const [count, setCount] = useState(0);

    return (
        <>
            <p>Count: {count}</p>
            <button onClick={() => setCount(count + 1)}>+</button>
            <p>Calculation: {count * 2}</p>
        </>
    );
};
Enter fullscreen mode Exit fullscreen mode

Even if we pretend that the calculation is extremely expensive, there are better solutions for that as well:

import { useMemo, useState } from "react";

const Counter = () => {
    const [count, setCount] = useState(0);
    const calculation = useMemo(() => count * 2, [count]);

    return (
        <>
            <p>Count: {count}</p>
            <button onClick={() => setCount(count + 1)}>+</button>
            <p>Calculation: {calculation}</p>
        </>
    );
};
Enter fullscreen mode Exit fullscreen mode

You might want to take a look at the new docs about useEffect and also I suggest you follow Dan Abramov on Twitter, who's lately working on those docs and making very clear how little we actually need the useEffect hook.

Cheers!

Collapse
gass profile image
Gass • Edited on

It's an easy way of explaining and understanding how useEffect works. But I agree. Maybe it would be better to create an example using something like window dimensions which from my point of view requires the useEffect hook. Needed for adding and removing the event listener.

useWindowDimensions custom hook

From React docs

The clean-up function runs before the component is removed from the UI to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the previous effect is cleaned up before executing the next effect.

Collapse
ayo_dev profile image
Talabi Ayomide Author

Thanks for your addition. This isn't a sophisticated example,it was just to help beginners up and running.