Q) Let’s say their is an API and I want you run it on the first page load , how can you do it ?
Ans. Yes! We need useEffect for that .
useEffect is something which helps us to perform side effects in our react application
Now what is side effect?
Side effect is something which gives unpredictable output / result or actions which are performed by the outside world.
Some common example of side effect are –
- making an API request
- unpredictable async functions call , etc.
Not only this, side effect don’t hinder the rendering or performance of the react function while interacting with the outside world.
Let’s see useEffect practically
Basic Syntax –
import { useEffect } from 'react';
function MyComponent() {
useEffect(() => {}, []);
// return ...
}
Component mounted for the first time –
Replacement for “componentDidMount“
import React, { useEffect } from "react";
const A = () => {
console.log("component mounted"); //first
useEffect(() => {
console.log("use effect called"); //second
});
return <div>A</div>;
};
export default A;
In the above function , the data under useEffect will be printed once component is mounted for the first time.
Component update using useEffect and dependency array
Replacement for “componentDidUpdate“
import React, { useEffect, useState } from "react";
const A = () => {
var [counter, setCounter] = useState(0);
var [counter2, setCounter2] = useState(0);
console.log("component mounted");
console.log("component did updated");
useEffect(() => {
console.log("use effect called");
}, [counter]);
return (
<div>
<h1> Component A </h1>
<h2>{counter}</h2>
<button onClick={() => setCounter(counter + 1)}>Click me</button>
<br />
<h2>{counter2}</h2>
<button onClick={() => setCounter2(counter2 + 1)}>Click me</button>
</div>
);
};
export default A;
Here useEffect will only run when the value inside dependency array will update/change.
This is why
- when the value of “counter” changes , useEffect will run.
- when the value of “counter2” changes , useEffect did not run.
Dependency array prevent from infinite loop
import React, { useEffect, useState } from "react";
const B = () => {
var [data1, setData] = useState();
async function getUserData() {
const data = await fetch("https://api.github.com/users");
const response = await data.json();
// console.log(response);
setData(response);
}
//infinite loop , wrong way
useEffect(() => {
console.log("use effect called");
getUserData();
});
//correct way using dependecy array
useEffect(() => {
console.log("use effect called");
getUserData();
});
return (
<div>
<h1>fds</h1>
{data1?.map((each, index) => (
<p key={index}>{each.login}</p>
))}
</div>
);
};
export default B;
1. useEffect(() => {});
it will run after every render.
2. useEffect(() => {}, []);
it will run once after the component has rendered the first time.
3. useEffect(() => {}, [value1 , value2]);
it will only run when the value inside array will update
Component unmounted using useEffect – Cleanup function
Replacement for “componentWillUnmount“
Sometimes we need to stop the subscription , or stop the side effect intertionally, that time we need a cleanup function.
This is an optional function.
Syntax –
useEffect(() => {
console.log("use effect called");
return () => {
console.log("component unmounted");
};
}, [counter]);
Important thing to keep in head about useEffect()
- useEffect() take 2 argument : a function and a dependency array(optional)
- it helps to run a function which need to be run on first render / every page load / conditional render , etc
- function inside useEffect() will be called after component has been rendered.
Hope you have understood and found it helpful.