Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende The Effect Hook | Hooks
Introduction to React

book
The Effect Hook

The effect hook lets us perform side effects inside the component. For example, fetching data from an API, running a timer, updating another component/element, etc.

We will try to understand the importance and usefulness of effect hook by looking at an example.

Let's try making a simple component that contains a <h1> element. The element displays the text from the message state variable. We will use a timer inside the component function to update the message text after 4 seconds:

js
import React, { useState } from "react";
import ReactDOM from "react-dom/client";
function Main(props) {
const [ message, updateMessage ] = useState("This is a sentence.");
setTimeout(() => {
updateMessage("This is another message!");
console.log("Timer Function Executed!");
}, 4000);
return (<h1>{message}</h1>);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Main />);

Note that we also included a console.log statement inside the timer function for debugging.

If we use the above code, the output should be something like this:

carousel-imgcarousel-img

It does change the text after four seconds, however, if you look at the console, the log indicates that the timer function has been called multiple times!

This is because every time the component is re-rendered, the component's function is re-executed, and since the component's function contains the timer code as well, the timer runs again. This is not what we want.

This can be especially problematic in cases, for example, when we make API calls or perform other tasks that are not supposed to be repeated.

The useEffect function lets us perform tasks like these without worrying about how often the component will be re-rendered.

The function passed into useEffect is executed independently of how often the component is re-rendered.

The syntax for the useEffect is the following:

js
useEffect(<function>, <dependency>)

Here <function> is usually an inline function that contains the code for performing the side effect we want, and <dependency> is supposed to be an array of terms (or values) that are supposed to be tracked for any changes.

The inline function will be executed if there are changes in any of the dependencies.

js
function Main(props) {
const [ count, setCount ] = useState(1);
const [ tens, setTens ] = useState(0);
setTimeout(() => {
if(count % 10 == 0)
setTens(tens + 1);
setCount(count + 1);
console.log (count);
}, 500);
useEffect(() => {
console.log(`useEffect called`);
}, [tens]);
return (<h1>Count: {count}</h1>);
}

In the above code, on every 10th value, the state variable tens is incremented. useEffect is set to execute only when there are changes in tens.

We can see the debug log to confirm this:

If you look at the console, "useEffect called" is printed after every 10th value.

However, if we pass an empty array as a dependency in the useEffect function, the function will execute only once after the first render.

This can be used to fix our first example:

js
function Main(props) {
const [ message, updateMessage ] = useState("This is a sentence.");
useEffect(() => {
setTimeout(() => {
updateMessage("This is another message!");
console.log("Timer Function Executed!");
}, 4000);
}, []);
return (<h1>{message}</h1>);
}

The console will show only one log statement since the function is executed only once:

Summary:

js
useEffect(() => {
// Will execute every render
})

useEffect(() => {
// Will execute only once
}, []);

useEffect(() => {
// Will execute of any of the 'var_a', 'var_b', 'var_c' changes
}, [var_a, var_b, var_c]);

Note

You can use useEffect multiple times in a single component based on the needs.

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 6. Capítulo 3

Pregunte a AI

expand
ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

some-alt