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.