React JS

What is useEffect() in React?

Interview Answer

useEffect() is a React Hook used to perform side effects such as API calls, timers, event listeners, and DOM updates in Functional Components. It runs after the component renders. By using the dependency array, we can control when the effect executes. An empty array runs it once on mount, specific dependencies run it when those values change, and a cleanup function is used when the component unmounts.

What is useEffect() in React?

useEffect() is a React Hook used to perform side effects in Functional Components.

Examples of Side Effects

  • API calls
  • Database requests
  • Timers (setInterval, setTimeout)
  • Event listeners
  • Updating document title
  • Local Storage operations

Syntax

useEffect(() => {
// code to execute
}, [dependencies]);

Structure

useEffect(
() => {
// Effect Code
},
[dependencies]
);
  • First argument → Function to execute
  • Second argument → Dependency array

1. useEffect with Empty Dependency Array

import { useEffect } from "react";

function User() {

useEffect(() => {
console.log("Component Loaded");
}, []);

return <h1>User Page</h1>;
}

Output

Component Loaded

Runs only once when the component is mounted.

Equivalent Class Component:

componentDidMount() {
console.log("Component Loaded");
}

2. useEffect Without Dependency Array

useEffect(() => {
console.log("Executed");
});

Runs after every render.

Example

function Counter() {
const [count, setCount] = useState(0);

useEffect(() => {
console.log("Effect Executed");
});

return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}

Every click causes:

Effect Executed

because component re-renders.


3. useEffect with Dependency Array

useEffect(() => {
console.log("Count Changed");
}, [count]);

Runs only when count changes.

Example

function Counter() {
const [count, setCount] = useState(0);

useEffect(() => {
console.log("Count Updated");
}, [count]);

return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}

Execution Flow

Initial Load:

Render Component

Display UI

useEffect Executes

Count Change:

setCount()

Component Re-renders

UI Updates

useEffect Executes

Cleanup Function

Used when component is removed.

useEffect(() => {

console.log("Mounted");

return () => {
console.log("Unmounted");
};

}, []);

Output

Mounted
Unmounted

Equivalent Class Component:

componentDidMount()
componentWillUnmount()

Real Project Example: API Call

import { useEffect, useState } from "react";

function Users() {

const [users, setUsers] = useState([]);

useEffect(() => {

fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(data => setUsers(data));

}, []);

return (
<>
{users.map(user => (
<p key={user.id}>{user.name}</p>
))}
</>
);
}

Why []?

Without it:

useEffect(() => {
fetchUsers();
});

The API would execute after every render and may create an infinite loop if state updates inside the effect.


Common Mistake

useEffect(() => {
setCount(count + 1);
}, [count]);

This creates:

count changes

useEffect runs

setCount()

count changes again

useEffect runs again

Result: Infinite re-render loop.