HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS DSA TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI R GO KOTLIN SASS VUE GEN AI SCIPY CYBERSECURITY DATA SCIENCE INTRO TO PROGRAMMING BASH RUST
React useEffect Hooks
The useEffect Hook allows you to perform side effects in your components.
Some examples of side effects are: fetching data, directly updating the DOM, and timers.
useEffect accepts two arguments. The second argument is optional.
useEffect(, )
Let's use a timer as an example.
Example:Get your own React.js Server
Use setTimeout() to count 1 second after initial render:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
});
return
I've rendered {count} times!
;}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render();
But wait!! It keeps counting even though it should only count once!
useEffect runs on every render. That means that when the count changes, a render happens, which then triggers another effect.
This is not what we want. There are several ways to control when side effects run.
We should always include the second parameter which accepts an array. We can optionally pass dependencies to useEffect in this array.
Example
- No dependency passed:
useEffect(() => {
//Runs on every render
});
Example
- An empty array:
useEffect(() => {
//Runs only on the first render
}, []);
Example
- Props or state values:
useEffect(() => {
//Runs on the first render
//And any time any dependency value changes
}, [prop, state]);
So, to fix this issue, let's only run this effect on the initial render.
Example:
Only run the effect on the initial render:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
}, []); // <- add empty brackets here
return
I've rendered {count} times!
;}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render();
Example:
Here is an example of a useEffect Hook that is dependent on a variable. If the count variable updates, the effect will run again:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
function Counter() {
const [count, setCount] = useState(0);
const [calculation, setCalculation] = useState(0);
useEffect(() => {
setCalculation(() => count * 2);
}, [count]); // <- add the count variable here
return (
<>
Count: {count}
setCount((c) => c + 1)}>+
Calculation: {calculation}
</>
);
}
const [count, setCount] = useState(0);
useEffect(() => {
let timer = setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
return () => clearTimeout(timer)
}, []);
return
I've rendered {count} times!
;}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render();
Note: To clear the timer, we had to name it.
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render();
If there are multiple dependencies, they should be included in the useEffect dependency array
Top comments (0)