PT-BR EN
Blog

How to Use useEffect

3 min read
How to Use useEffect

What is useEffect?

Imagine you are building a web interface that consumes data from outside your front end. Maybe from an API.

Then you end up thinking:

I want to store a value and update the interface whenever it changes.

That is exactly what useEffect is for. It is used when a component needs to run a side effect after a render, usually to sync something external to React with the component’s state/props.

Side effects

A function has a side effect when, besides computing a value, say, it causes some change or interaction outside of its own computation. useEffect is a hook that represents the side effect caused by rendering or by changes in the component’s dependencies.

Parameters

The conceptual signature of useEffect is:

useEffect(effect, dependencies)

It takes 2 parameters:

  • effect: The function that will run as the effect;
  • dependencies: An optional array that determines when the effect should run again.

Return value

Unlike useState, useEffect doesn’t have a return value, but the function passed to it may return a cleanup function.

useEffect(() => {
  const timer = setInterval(() => {
    console.log("hi");
  }, 1000);

  return () => {
    clearInterval(timer);
  };
}, []);

This code creates a timer that runs a console.log(“hi”) every 1 second while the component is mounted. When the component unmounts, the cleanup function clearInterval(timer) is called, stopping the timer.

The component lifecycle in React

We can simplify the React component lifecycle into 3 phases:

  • Mount: When the component appears for the first time
  • Update: Happens when the component goes through some change that causes a new render, such as
    • State changes
    • Props changes
    • Context changes
    • Renders caused by the parent element
  • Unmount: Happens when the component stops existing in the React tree.

For class components, we can rely on these lifecycle methods.

For function components, we can manage this lifecycle with the useEffect hook.

componentDidMount

In a class component

  class App extends React.Component {
    componentDidMount() {
      console.log('mounted');
    }

    render() {
      return <h1>Hello</h1>;
    }
  }

With useEffect

function App(){
  useEffect(() => {
    console.log('mounted');
  }, []);
}

The [] is important to make the function run only on the initial mount.

componentDidUpdate

In a class component

  componentDidUpdate() {
    console.log('updated');
  }

With useEffect

useEffect(() => {
  console.log('updated');
});

Without the dependency array, it will run on every render.

useEffect(() => {
  console.log('counter changed');
}, [counter]);

In this case, it runs when the counter value changes.

componentWillUnmount

In a class component

componentWillUnmount() {
  console.log('will unmount');
}

With useEffect

useEffect(() => {
  return () => {
    console.log('will unmount');
  };
}, []);

The function’s return value is the cleanup.

Examples

In this example, the dark color is enabled every time the counter updates.

In this example, setGreetings is passed as a prop to the SayHi component. The useEffect creates a timer on mount that adds a new greeting every second. When the component unmounts, this timer is cleaned up. Try removing the clearInterval. A curious bug will cause new timers to be created without clearing the timer when the component unmounts.