> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anujpandey.in/llms.txt
> Use this file to discover all available pages before exploring further.

# useEffect

# 🧠 React `useEffect` — In-Depth Theory Guide

***

# 1. Introduction

## 🔹 What is `useEffect`?

`useEffect` is a **React Hook** used to handle **side effects** in functional components.

A *side effect* is anything that:

* Interacts with the outside world
* Happens outside the render cycle

Examples:

* API calls
* DOM manipulation
* Subscriptions (WebSocket, event listeners)
* Timers (`setTimeout`, `setInterval`)
* Logging

👉 In simple terms:

> `useEffect` lets you run code **after React renders your component**

***

## 🔹 Why is it important in React?

React components are expected to be **pure functions**:

* Same input → same output (UI)

But real apps need:

* Data fetching
* Event handling
* External sync

`useEffect` bridges:

> **Pure UI rendering ↔ Imperative side effects**

Without `useEffect`, handling real-world behavior would be messy and unpredictable.

***

## 🔹 When and why we use it

Use `useEffect` when you need to:

### ✅ Synchronize with external systems

* APIs
* Browser APIs
* Third-party libraries

### ✅ React to state or prop changes

* Fetch new data when ID changes
* Update title when state updates

### ✅ Manage lifecycle-like behavior

* Component mount
* Component update
* Component unmount

***

# 2. Concepts / Internal Workings

***

## 🔹 Core Concept: Effects run *after render*

React lifecycle (functional component):

1. Render phase (pure)
2. Commit phase (DOM updated)
3. **Effect phase (useEffect runs here)**

👉 Effects **never block rendering**

***

## 🔹 Types of Effects

### 1. Passive Effects (`useEffect`)

* Run **after paint**
* Non-blocking
* Used for most cases

### 2. Layout Effects (`useLayoutEffect`)

* Run **before paint**
* Blocking
* Used for DOM measurement

***

## 🔹 Dependency Array (Critical Concept)

```js theme={null}
useEffect(() => {
  // effect logic
}, [dependencies]);
```

### Behavior:

| Dependency | Behavior              |
| ---------- | --------------------- |
| `[]`       | Runs once (on mount)  |
| `[x]`      | Runs when `x` changes |
| no array   | Runs on every render  |

***

## 🔹 Closures & Stale Data

Effects capture values from the render they were created in.

```js theme={null}
useEffect(() => {
  console.log(count);
}, []);
```

⚠️ Problem:

* `count` will always be the initial value (stale closure)

***

## 🔹 Cleanup Function

```js theme={null}
useEffect(() => {
  const id = setInterval(() => {}, 1000);

  return () => {
    clearInterval(id);
  };
}, []);
```

### Why cleanup matters:

* Prevent memory leaks
* Remove subscriptions
* Avoid duplicate side effects

***

## 🔹 Internal Working (Simplified)

React internally:

1. Stores effects in a queue during render
2. After commit:

   * Runs cleanup (if exists)
   * Runs new effect

👉 Order:

```
Render → Commit → Cleanup → Effect
```

***

## 🔹 Relationship with Other React Features

### 1. `useState`

* Effects often depend on state changes

### 2. `useRef`

* Used to persist values across renders without triggering effects

### 3. `useMemo` / `useCallback`

* Prevent unnecessary effect re-runs

### 4. Concurrent Rendering (React 18+)

* Effects may run more than once in dev (Strict Mode)
* Helps detect unsafe side effects

***

# 3. Syntax & Examples

***

## 🔹 Basic Syntax

```js theme={null}
useEffect(() => {
  // side effect
}, [dependencies]);
```

***

## 🔹 1. Run Once (Component Mount)

```js theme={null}
useEffect(() => {
  console.log("Component mounted");
}, []);
```

***

## 🔹 2. Run on State Change

```js theme={null}
const [count, setCount] = useState(0);

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

***

## 🔹 3. API Call Example

```js theme={null}
useEffect(() => {
  fetch("/api/data")
    .then(res => res.json())
    .then(data => console.log(data));
}, []);
```

***

## 🔹 4. Cleanup Example (Event Listener)

```js theme={null}
useEffect(() => {
  const handleResize = () => console.log(window.innerWidth);

  window.addEventListener("resize", handleResize);

  return () => {
    window.removeEventListener("resize", handleResize);
  };
}, []);
```

***

## 🔹 5. Interval Example

```js theme={null}
useEffect(() => {
  const id = setInterval(() => {
    console.log("Running...");
  }, 1000);

  return () => clearInterval(id);
}, []);
```

***

## 🔹 6. Derived Effect (Multiple Dependencies)

```js theme={null}
useEffect(() => {
  console.log("User or filter changed");
}, [user, filter]);
```

***

## 🔹 7. Conditional Effect

```js theme={null}
useEffect(() => {
  if (!user) return;

  fetchUserData(user.id);
}, [user]);
```

***

## 🔹 8. Avoiding Stale Closures

```js theme={null}
useEffect(() => {
  const id = setInterval(() => {
    setCount(prev => prev + 1);
  }, 1000);

  return () => clearInterval(id);
}, []);
```

***

## 🔹 9. Splitting Effects (Best Pattern)

❌ Bad:

```js theme={null}
useEffect(() => {
  fetchData();
  document.title = "Hello";
}, []);
```

✅ Good:

```js theme={null}
useEffect(() => {
  fetchData();
}, []);

useEffect(() => {
  document.title = "Hello";
}, []);
```

***

# 4. Edge Cases / Common Mistakes

***

## 🔴 1. Missing Dependencies

```js theme={null}
useEffect(() => {
  fetchData(id);
}, []); // ❌ id missing
```

Problem:

* Effect uses stale `id`

Fix:

```js theme={null}
}, [id]);
```

***

## 🔴 2. Infinite Loops

```js theme={null}
useEffect(() => {
  setCount(count + 1);
}, [count]);
```

👉 Causes infinite re-renders

Fix:

* Use condition OR rethink logic

***

## 🔴 3. Function Dependencies

```js theme={null}
useEffect(() => {
  fetchData();
}, [fetchData]); // ⚠️ unstable reference
```

Fix:

```js theme={null}
const fetchData = useCallback(() => {}, []);
```

***

## 🔴 4. Object/Array Dependencies

```js theme={null}
useEffect(() => {}, [{ a: 1 }]); // ❌ new reference every render
```

Fix:

* Memoize or extract outside

***

## 🔴 5. Strict Mode Double Execution

In development:

```js theme={null}
useEffect(() => {
  console.log("Runs twice");
}, []);
```

👉 Expected in React 18 Strict Mode

Purpose:

* Detect side effects issues

***

## 🔴 6. Async Directly in Effect

```js theme={null}
useEffect(async () => {}); // ❌
```

Fix:

```js theme={null}
useEffect(() => {
  const fetchData = async () => {};
  fetchData();
}, []);
```

***

## 🔴 7. Race Conditions (API Calls)

```js theme={null}
useEffect(() => {
  fetch(`/api/${id}`).then(setData);
}, [id]);
```

Problem:

* Older request may override new one

Fix:

* Use abort controller or track latest request

***

# 5. Best Practices

***

## ✅ 1. Keep Effects Focused

👉 One effect = one responsibility

***

## ✅ 2. Always Declare Dependencies Correctly

* Use ESLint plugin: `react-hooks/exhaustive-deps`

***

## ✅ 3. Prefer Derived State over Effects

❌ Avoid:

```js theme={null}
useEffect(() => {
  setFullName(first + last);
}, [first, last]);
```

✅ Prefer:

```js theme={null}
const fullName = first + last;
```

***

## ✅ 4. Use Cleanup Properly

* Always clean:

  * timers
  * subscriptions
  * listeners

***

## ✅ 5. Avoid Overusing `useEffect`

👉 If it can be computed during render → don’t use effect

***

## ✅ 6. Memoize Dependencies When Needed

Use:

* `useCallback`
* `useMemo`

***

## ✅ 7. Handle Async Safely

```js theme={null}
useEffect(() => {
  let isMounted = true;

  fetchData().then(data => {
    if (isMounted) setData(data);
  });

  return () => {
    isMounted = false;
  };
}, []);
```

***

## ✅ 8. Think in Synchronization, Not Lifecycle

Instead of:

> “Run this on mount”

Think:

> “Keep this in sync with X”

***

## ✅ 9. Use Custom Hooks for Reusability

```js theme={null}
function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handler = () => setWidth(window.innerWidth);
    window.addEventListener("resize", handler);

    return () => window.removeEventListener("resize", handler);
  }, []);

  return width;
}
```

***

# 🚀 Final Mental Model

> `useEffect` is not about lifecycle — it’s about **synchronizing your component with external systems after render**

***

# 🧠 Advanced `useEffect` — Senior-Level Interview Questions & Answers

***

# 1. What problem does `useEffect` actually solve in React’s architecture?

### ✅ Answer

`useEffect` exists to **separate pure rendering from side effects**.

### 🔍 WHY this matters

React’s rendering model is based on **pure functions**:

```js theme={null}
UI = f(state, props)
```

But real applications require:

* Network calls
* DOM APIs
* Subscriptions

These are **impure operations**.

👉 `useEffect` ensures:

* Rendering stays pure
* Side effects run **after commit phase**

### 🧠 Key Insight

> `useEffect` is not about lifecycle — it’s about **synchronization with external systems**

***

# 2. Why are effects executed after the commit phase and not during render?

### ✅ Answer

Because React needs rendering to remain:

* **Deterministic**
* **Interruptible (Concurrent Mode)**

### 🔍 WHY

If effects ran during render:

* They could block rendering
* They could cause inconsistent UI
* They would break concurrent rendering

### 🔄 Internal Flow

```
Render → Commit DOM → Run Effects
```

### 🧠 Insight

> Effects are deferred to ensure React can prioritize UI updates without side-effect interference

***

# 3. How does React determine whether to re-run an effect?

### ✅ Answer

React performs a **shallow comparison** of dependency array values using `Object.is`.

```js theme={null}
useEffect(() => {}, [dep]);
```

### 🔍 WHY shallow comparison?

* Performance: deep comparison is expensive
* Predictability: reference equality is consistent

### ⚠️ Implication

```js theme={null}
useEffect(() => {}, [{ a: 1 }]); // always re-runs
```

Because:

* New object reference each render

### ✅ Solution

```js theme={null}
const memoObj = useMemo(() => ({ a: 1 }), []);
```

***

# 4. What are “stale closures” in `useEffect`, and why do they occur?

### ✅ Answer

A stale closure happens when an effect **captures outdated values** from a previous render.

```js theme={null}
useEffect(() => {
  console.log(count);
}, []);
```

### 🔍 WHY it happens

* Functions in React **close over variables at render time**
* Effect runs later, but uses old values

### 🧠 Fix strategies

1. Add dependency:

```js theme={null}
}, [count]);
```

2. Functional updates:

```js theme={null}
setCount(prev => prev + 1);
```

### 🧠 Insight

> Effects don’t “see” updates unless dependencies tell them to

***

# 5. Why does React Strict Mode run effects twice in development?

### ✅ Answer

To detect:

* Unsafe side effects
* Missing cleanup logic

### 🔍 WHY

React simulates:

1. Mount
2. Unmount
3. Re-mount

```js theme={null}
useEffect(() => {
  console.log("Runs twice in dev");
}, []);
```

### 🧠 Insight

> If your effect breaks under double execution → it's not safe

***

# 6. What is the difference between `useEffect` and `useLayoutEffect`?

### ✅ Answer

| Feature  | useEffect          | useLayoutEffect |
| -------- | ------------------ | --------------- |
| Timing   | After paint        | Before paint    |
| Blocking | No                 | Yes             |
| Use case | Async side effects | DOM measurement |

### 🔍 WHY distinction exists

To allow:

* Performance optimization (`useEffect`)
* Layout correctness (`useLayoutEffect`)

### Example

```js theme={null}
useLayoutEffect(() => {
  const rect = ref.current.getBoundingClientRect();
}, []);
```

***

# 7. Why is putting async directly in `useEffect` discouraged?

### ✅ Answer

Because `useEffect` expects:

* A function OR
* A cleanup function

But `async` returns a Promise.

```js theme={null}
useEffect(async () => {}); // ❌
```

### 🔍 Correct pattern

```js theme={null}
useEffect(() => {
  async function fetchData() {}
  fetchData();
}, []);
```

### 🧠 Insight

> Cleanup must be synchronous → async breaks contract

***

# 8. How do race conditions occur in effects, and how do you prevent them?

### ✅ Answer

Race condition:

* Multiple async calls → responses arrive out of order

```js theme={null}
useEffect(() => {
  fetch(`/api/${id}`).then(setData);
}, [id]);
```

### 🔍 Problem

* Old request may overwrite new state

### ✅ Fix: AbortController

```js theme={null}
useEffect(() => {
  const controller = new AbortController();

  fetch(`/api/${id}`, { signal: controller.signal })
    .then(res => res.json())
    .then(setData);

  return () => controller.abort();
}, [id]);
```

### 🧠 Insight

> Effects must handle async cancellation explicitly

***

# 9. Why is splitting effects considered a best practice?

### ✅ Answer

Because effects represent **independent synchronization processes**.

### ❌ Bad

```js theme={null}
useEffect(() => {
  fetchData();
  document.title = "Hello";
}, []);
```

### ✅ Good

```js theme={null}
useEffect(fetchData, []);
useEffect(() => {
  document.title = "Hello";
}, []);
```

### 🔍 WHY

* Better separation of concerns
* Easier debugging
* Correct dependency tracking

***

# 10. When should you NOT use `useEffect`?

### ✅ Answer

When logic can be computed during render.

### ❌ Bad

```js theme={null}
useEffect(() => {
  setFullName(first + last);
}, [first, last]);
```

### ✅ Good

```js theme={null}
const fullName = first + last;
```

### 🧠 Insight

> Effects are for **side effects**, not derived state

***

# 11. Why can functions in dependency arrays cause unnecessary re-renders?

### ✅ Answer

Because functions are recreated every render.

```js theme={null}
useEffect(() => {}, [handleClick]);
```

### 🔍 WHY

* New reference → dependency changed → effect runs again

### ✅ Fix

```js theme={null}
const handleClick = useCallback(() => {}, []);
```

***

# 12. How does React schedule and clean up effects internally?

### ✅ Answer

React maintains:

* Effect list per fiber

### Execution order:

1. Cleanup previous effect
2. Run new effect

```js theme={null}
Render → Commit → Cleanup → Effect
```

### 🧠 Insight

> Cleanup always runs **before next effect**, not just on unmount

***

# 13. What happens if you omit dependencies entirely?

### ✅ Answer

```js theme={null}
useEffect(() => {});
```

Runs on:

* Every render

### 🔍 WHY

React assumes:

* Effect depends on everything

### ⚠️ Risk

* Performance issues
* Infinite loops

***

# 14. How do you debug an infinite loop caused by `useEffect`?

### ✅ Answer

### Step-by-step:

1. Identify state updates inside effect
2. Check dependencies

```js theme={null}
useEffect(() => {
  setCount(count + 1);
}, [count]);
```

### 🔍 Fix strategies

* Add condition
* Remove unnecessary state updates
* Use functional updates

***

# 15. What is the conceptual difference between lifecycle methods and `useEffect`?

### ✅ Answer

| Lifecycle  | useEffect        |
| ---------- | ---------------- |
| Imperative | Declarative      |
| Time-based | Dependency-based |

### 🔍 WHY React moved away

Class lifecycle:

* Fragmented logic
* Hard to reason about

Hooks:

* Co-locate logic by concern

### 🧠 Insight

> `useEffect` expresses “sync with X” instead of “run at time Y”

***

# 16. How do you handle subscriptions correctly in `useEffect`?

### ✅ Answer

Always:

* Subscribe in effect
* Unsubscribe in cleanup

```js theme={null}
useEffect(() => {
  socket.subscribe();

  return () => socket.unsubscribe();
}, []);
```

### 🔍 WHY

* Prevent memory leaks
* Avoid duplicate listeners

***

# 17. What are the trade-offs of using `useEffect` heavily?

### ✅ Answer

### Pros:

* Flexible
* Handles all side effects

### Cons:

* Hard to reason about dependencies
* Risk of bugs (stale closures, loops)
* Overuse leads to messy code

### 🧠 Alternative approaches

* Derived state
* Event handlers
* Custom hooks
* Server-side data fetching (Next.js)

***

# 18. How do custom hooks improve `useEffect` usage?

### ✅ Answer

They:

* Encapsulate effect logic
* Improve reusability
* Hide complexity

### Example

```js theme={null}
function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {
    const update = () => setIsOnline(navigator.onLine);

    window.addEventListener("online", update);
    window.addEventListener("offline", update);

    return () => {
      window.removeEventListener("online", update);
      window.removeEventListener("offline", update);
    };
  }, []);

  return isOnline;
}
```

***

# 🚀 Final Takeaway

> Senior-level understanding of `useEffect` is not about syntax — it’s about **thinking in synchronization, managing side effects safely, and avoiding unnecessary effects altogether**

***

# 🧠 Advanced `useEffect` — Senior-Level MCQs

***

## **1. What will be logged and why?**

```js theme={null}
function App() {
  const [count, setCount] = useState(0);

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

  return <button onClick={() => setCount(5)}>Click</button>;
}
```

### Options:

A. `0` on mount, then `5` after click
B. Only `0`
C. Only `5`
D. Nothing logged

### ✅ Correct Answer: **B**

### 💡 Explanation:

* Effect runs only once (`[]`)
* Closure captures `count = 0`
* Even after state updates, effect does NOT re-run

### ❌ Why others are wrong:

* A: Effect doesn’t re-run after click
* C: Effect already executed before update
* D: Effect runs on mount

***

## **2. What happens here?**

```js theme={null}
useEffect(() => {
  setCount(count + 1);
}, [count]);
```

### Options:

A. Runs once
B. Runs twice
C. Infinite loop
D. Throws error

### ✅ Correct Answer: **C**

### 💡 Explanation:

* Updating `count` triggers re-render
* Dependency changes → effect runs again
* Loop continues indefinitely

### ❌ Why others are wrong:

* A/B: No stopping condition
* D: No runtime error, just loop

***

## **3. Which fix prevents unnecessary effect re-runs?**

```js theme={null}
useEffect(() => {
  fetchData();
}, [fetchData]);
```

### Options:

A. Remove dependency array
B. Wrap `fetchData` in `useMemo`
C. Wrap `fetchData` in `useCallback`
D. Move `fetchData` inside effect

### ✅ Correct Answer: **C (Best)**

### 💡 Explanation:

* Functions change reference every render
* `useCallback` stabilizes reference

### ⚖️ Nuance:

* D also works, but not always ideal (less reusable)

### ❌ Why others are wrong:

* A: Runs every render
* B: `useMemo` is for values, not functions

***

## **4. What happens in Strict Mode (React 18)?**

```js theme={null}
useEffect(() => {
  console.log("Effect");
}, []);
```

### Options:

A. Runs once
B. Runs twice (dev only)
C. Runs twice (prod + dev)
D. Runs randomly

### ✅ Correct Answer: **B**

### 💡 Explanation:

* Strict Mode intentionally double-invokes effects
* Helps detect unsafe side effects

***

## **5. What is the issue here?**

```js theme={null}
useEffect(() => {
  fetch(`/api/${id}`).then(setData);
}, []);
```

### Options:

A. Missing dependency
B. Memory leak
C. Infinite loop
D. Syntax error

### ✅ Correct Answer: **A**

### 💡 Explanation:

* `id` is used but not declared as dependency
* Effect won’t update when `id` changes

***

## **6. What is the main risk here?**

```js theme={null}
useEffect(() => {
  const id = setInterval(() => {
    console.log("tick");
  }, 1000);
}, []);
```

### Options:

A. Infinite loop
B. Memory leak
C. Performance optimization
D. No issue

### ✅ Correct Answer: **B**

### 💡 Explanation:

* Interval is never cleared
* Continues even after unmount

***

## **7. Which is TRUE about dependency comparison?**

### Options:

A. Deep comparison
B. Reference comparison (`Object.is`)
C. JSON stringify comparison
D. Random comparison

### ✅ Correct Answer: **B**

***

## **8. What happens here?**

```js theme={null}
useEffect(() => {
  console.log("run");
}, [{ a: 1 }]);
```

### Options:

A. Runs once
B. Never runs
C. Runs every render
D. Throws error

### ✅ Correct Answer: **C**

### 💡 Explanation:

* New object created each render
* Reference always different

***

## **9. What is the best fix?**

```js theme={null}
useEffect(() => {
  doSomething(obj);
}, [obj]);
```

Where `obj = { a: 1 }` inside component.

### Options:

A. Ignore it
B. Move object outside component
C. Memoize with `useMemo`
D. Both B and C

### ✅ Correct Answer: **D**

***

## **10. What is logged?**

```js theme={null}
useEffect(() => {
  console.log("A");

  return () => console.log("B");
}, [count]);
```

When `count` changes.

### Options:

A. A
B. B → A
C. A → B
D. B only

### ✅ Correct Answer: **B**

### 💡 Explanation:

* Cleanup runs before next effect
* Order: **B (cleanup) → A (new effect)**

***

## **11. What is wrong here?**

```js theme={null}
useEffect(async () => {
  const data = await fetchData();
  setData(data);
}, []);
```

### Options:

A. Nothing
B. Async not allowed
C. Cleanup breaks
D. Both B and C

### ✅ Correct Answer: **D**

***

## **12. What is the best pattern for async?**

### Options:

A.

```js theme={null}
useEffect(async () => {})
```

B.

```js theme={null}
useEffect(() => {
  async function load() {}
  load();
}, []);
```

C.

```js theme={null}
useEffect(() => Promise.resolve())
```

D.

```js theme={null}
useEffect(() => {}, async [])
```

### ✅ Correct Answer: **B**

***

## **13. Which scenario causes stale closure?**

### Options:

A.

```js theme={null}
useEffect(() => {
  console.log(count);
}, [count]);
```

B.

```js theme={null}
useEffect(() => {
  console.log(count);
}, []);
```

C.

```js theme={null}
useEffect(() => {
  setCount(prev => prev + 1);
}, []);
```

D. None

### ✅ Correct Answer: **B**

***

## **14. When should you use `useLayoutEffect` instead of `useEffect`?**

### Options:

A. API calls
B. Logging
C. DOM measurement before paint
D. Timers

### ✅ Correct Answer: **C**

***

## **15. What happens if dependency array is omitted?**

```js theme={null}
useEffect(() => {
  console.log("run");
});
```

### Options:

A. Runs once
B. Runs on every render
C. Runs only on state change
D. Never runs

### ✅ Correct Answer: **B**

***

## **16. What is the best alternative here?**

```js theme={null}
useEffect(() => {
  setFullName(first + last);
}, [first, last]);
```

### Options:

A. Keep as is
B. Move to render calculation
C. Use useMemo
D. Remove dependencies

### ✅ Correct Answer: **B**

### 💡 Explanation:

* Derived state → no need for effect

***

## **17. What is the issue here?**

```js theme={null}
useEffect(() => {
  fetch(`/api/${id}`).then(res => setData(res));
}, [id]);
```

### Options:

A. No issue
B. Race condition risk
C. Infinite loop
D. Memory leak only

### ✅ Correct Answer: **B**

***

## **18. Which solution prevents race conditions?**

### Options:

A. useMemo
B. AbortController
C. useRef only
D. setTimeout

### ✅ Correct Answer: **B**

***

## **19. Why is splitting effects recommended?**

### Options:

A. Faster rendering
B. Better separation of concerns
C. Required by React
D. Reduces bundle size

### ✅ Correct Answer: **B**

***

## **20. What is the conceptual model of `useEffect`?**

### Options:

A. Lifecycle replacement
B. Event system
C. Synchronization mechanism
D. State manager

### ✅ Correct Answer: **C**

***

# 🚀 Final Note

These questions test whether a candidate:

* Thinks in **synchronization vs lifecycle**
* Understands **React internals**
* Can handle **real-world edge cases**

***

# 🧠 Advanced `useEffect` — Real-World Coding Problems (Senior Level)

***

## **1. Data Fetch with Cancellation (Race Condition Handling)**

### 📌 Problem

Build a component that fetches user data when `userId` changes. Ensure that **older requests don’t overwrite newer ones**.

### Constraints

* API latency is unpredictable
* `userId` may change rapidly

### Expected Behavior

* Always show data for the **latest `userId`**
* Prevent stale updates

### Edge Cases

* Fast switching between IDs
* Component unmount during request

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  const controller = new AbortController();

  fetch(`/api/user/${userId}`, { signal: controller.signal })
    .then(res => res.json())
    .then(data => setUser(data))
    .catch(err => {
      if (err.name !== "AbortError") console.error(err);
    });

  return () => controller.abort();
}, [userId]);
```

### 🧠 Explanation

1. Each effect creates a new controller
2. Cleanup aborts previous request
3. Prevents stale response overwriting state

***

## **2. Debounced Search Input**

### 📌 Problem

Implement a search input that triggers API calls **only after user stops typing for 500ms**.

### Constraints

* Avoid excessive API calls
* Handle rapid typing

### Expected Behavior

* API called only after pause

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  const timeout = setTimeout(() => {
    if (query) fetchResults(query);
  }, 500);

  return () => clearTimeout(timeout);
}, [query]);
```

### 🧠 Explanation

* Timer resets on each keystroke
* Only last input triggers API

***

## **3. Window Resize Listener Hook**

### 📌 Problem

Track window width and update UI on resize.

### Edge Cases

* Component unmount
* Multiple listeners

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  const handleResize = () => setWidth(window.innerWidth);

  window.addEventListener("resize", handleResize);

  return () => window.removeEventListener("resize", handleResize);
}, []);
```

### 🧠 Explanation

* Cleanup prevents memory leaks
* Stable listener ensures correctness

***

## **4. Interval Counter with Correct State**

### 📌 Problem

Create a counter that increments every second.

### Edge Case

* Avoid stale closure

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  const id = setInterval(() => {
    setCount(prev => prev + 1);
  }, 1000);

  return () => clearInterval(id);
}, []);
```

### 🧠 Explanation

* Functional update avoids stale state

***

## **5. Sync Document Title with State**

### 📌 Problem

Update page title whenever `count` changes.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  document.title = `Count: ${count}`;
}, [count]);
```

### 🧠 Explanation

* Effect syncs external system (DOM)

***

## **6. Avoid Infinite Loop in Derived State**

### 📌 Problem

Compute `fullName` from `first` and `last`.

***

### ❌ Bad Approach

```js theme={null}
useEffect(() => {
  setFullName(first + last);
}, [first, last]);
```

***

### ✅ Solution

```js theme={null}
const fullName = first + last;
```

### 🧠 Explanation

* Derived state doesn’t need effect

***

## **7. API Polling System**

### 📌 Problem

Poll an API every 5 seconds.

### Constraints

* Stop polling on unmount

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  const id = setInterval(fetchData, 5000);
  return () => clearInterval(id);
}, []);
```

***

## **8. Conditional Fetch Based on Auth**

### 📌 Problem

Fetch user data only if `isLoggedIn` is true.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  if (!isLoggedIn) return;

  fetchUser();
}, [isLoggedIn]);
```

***

## **9. Sync LocalStorage with State**

### 📌 Problem

Persist theme preference.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  localStorage.setItem("theme", theme);
}, [theme]);
```

***

## **10. Initialize State from LocalStorage**

### 📌 Problem

Load saved value on mount.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  const saved = localStorage.getItem("theme");
  if (saved) setTheme(saved);
}, []);
```

***

## **11. Avoid Function Dependency Trap**

### 📌 Problem

Prevent effect re-run due to function reference.

***

### ✅ Solution

```js theme={null}
const fetchData = useCallback(() => {}, []);

useEffect(() => {
  fetchData();
}, [fetchData]);
```

***

## **12. Multiple Effects Separation**

### 📌 Problem

Fetch data and update title.

***

### ✅ Solution

```js theme={null}
useEffect(fetchData, []);

useEffect(() => {
  document.title = "Dashboard";
}, []);
```

***

## **13. WebSocket Subscription**

### 📌 Problem

Subscribe to a socket and clean up properly.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  socket.connect();

  return () => socket.disconnect();
}, []);
```

***

## **14. Prevent State Update After Unmount**

### 📌 Problem

Avoid setting state after component unmount.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  let mounted = true;

  fetchData().then(data => {
    if (mounted) setData(data);
  });

  return () => {
    mounted = false;
  };
}, []);
```

***

## **15. Scroll Position Tracker**

### 📌 Problem

Track scroll position.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  const handleScroll = () => setY(window.scrollY);

  window.addEventListener("scroll", handleScroll);

  return () => window.removeEventListener("scroll", handleScroll);
}, []);
```

***

## **16. Fetch with Retry Logic**

### 📌 Problem

Retry API call up to 3 times.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  let attempts = 0;

  const fetchWithRetry = async () => {
    try {
      const res = await fetch("/api");
      setData(await res.json());
    } catch {
      if (attempts < 3) {
        attempts++;
        fetchWithRetry();
      }
    }
  };

  fetchWithRetry();
}, []);
```

***

## **17. Dynamic Event Listener Based on Prop**

### 📌 Problem

Listen to different events based on prop.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  const handler = () => console.log("event");

  window.addEventListener(type, handler);

  return () => window.removeEventListener(type, handler);
}, [type]);
```

***

## **18. Avoid Multiple API Calls on Mount (Strict Mode)**

### 📌 Problem

Prevent duplicate API calls in dev mode.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  let called = false;

  if (!called) {
    fetchData();
    called = true;
  }
}, []);
```

### ⚠️ Better approach:

* Accept double call OR use external control (like caching)

***

## **19. Synchronize External Library**

### 📌 Problem

Initialize third-party library once.

***

### ✅ Solution

```js theme={null}
useEffect(() => {
  const instance = initLibrary();

  return () => instance.destroy();
}, []);
```

***

# 🚀 Final Takeaway

These problems test:

* **Effect lifecycle understanding**
* **Async control & cleanup**
* **Dependency correctness**
* **Real-world system thinking**

***

# 🧠 `useEffect` Debugging Challenges (Senior Code Review Level)

These simulate **real production bugs**—not syntax errors, but subtle issues around behavior, performance, and correctness.

***

# **1. Stale Closure in Interval**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  const id = setInterval(() => {
    setCount(count + 1);
  }, 1000);

  return () => clearInterval(id);
}, []);
```

### 🔍 What’s wrong?

`count` is always **stale (initial value)**.

### 💡 WHY it happens

* Effect runs once
* Closure captures initial `count`
* Never updates

### ✅ Fix

```js theme={null}
useEffect(() => {
  const id = setInterval(() => {
    setCount(prev => prev + 1);
  }, 1000);

  return () => clearInterval(id);
}, []);
```

### 🧠 Best Practice

Use **functional updates** when state depends on previous value.

***

# **2. Missing Dependency → Stale Data**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  fetch(`/api/user/${userId}`)
    .then(res => res.json())
    .then(setUser);
}, []);
```

### 🔍 What’s wrong?

Does not refetch when `userId` changes.

### 💡 WHY

Dependency array is incorrect → effect never re-runs

### ✅ Fix

```js theme={null}
}, [userId]);
```

### 🧠 Best Practice

Always include **all external values** used inside effect.

***

# **3. Infinite Loop from State Update**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  setFiltered(data.filter(item => item.active));
}, [filtered]);
```

### 🔍 What’s wrong?

Infinite loop.

### 💡 WHY

* Effect updates `filtered`
* `filtered` is dependency → triggers effect again

### ✅ Fix

```js theme={null}
useEffect(() => {
  setFiltered(data.filter(item => item.active));
}, [data]);
```

### 🧠 Best Practice

Never depend on **state you are setting inside the effect**.

***

# **4. Function Dependency Causing Re-Renders**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  fetchData();
}, [fetchData]);
```

### 🔍 What’s wrong?

Effect runs every render.

### 💡 WHY

Function recreated each render → new reference

### ✅ Fix

```js theme={null}
const fetchData = useCallback(() => {}, []);

useEffect(() => {
  fetchData();
}, [fetchData]);
```

### 🧠 Best Practice

Stabilize function references with `useCallback`.

***

# **5. Object Dependency Trap**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  doSomething(options);
}, [options]);
```

Where:

```js theme={null}
const options = { sort: "asc" };
```

### 🔍 What’s wrong?

Effect runs every render.

### 💡 WHY

New object reference each render

### ✅ Fix

```js theme={null}
const options = useMemo(() => ({ sort: "asc" }), []);
```

### 🧠 Best Practice

Avoid inline objects/arrays in dependencies.

***

# **6. Memory Leak from Event Listener**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  window.addEventListener("resize", handleResize);
}, []);
```

### 🔍 What’s wrong?

Listener never removed.

### 💡 WHY

No cleanup → memory leak

### ✅ Fix

```js theme={null}
useEffect(() => {
  window.addEventListener("resize", handleResize);

  return () => window.removeEventListener("resize", handleResize);
}, []);
```

### 🧠 Best Practice

Always clean up **subscriptions and listeners**.

***

# **7. Async Directly in Effect**

### ❌ Buggy Code

```js theme={null}
useEffect(async () => {
  const data = await fetchData();
  setData(data);
}, []);
```

### 🔍 What’s wrong?

Async function breaks effect contract.

### 💡 WHY

Effect expects cleanup function, not Promise

### ✅ Fix

```js theme={null}
useEffect(() => {
  async function load() {
    const data = await fetchData();
    setData(data);
  }
  load();
}, []);
```

***

# **8. Race Condition in Fetch**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  fetch(`/api/${id}`)
    .then(res => res.json())
    .then(setData);
}, [id]);
```

### 🔍 What’s wrong?

Older request may overwrite newer one.

### 💡 WHY

Async responses return out of order

### ✅ Fix

```js theme={null}
useEffect(() => {
  const controller = new AbortController();

  fetch(`/api/${id}`, { signal: controller.signal })
    .then(res => res.json())
    .then(setData)
    .catch(err => {
      if (err.name !== "AbortError") console.error(err);
    });

  return () => controller.abort();
}, [id]);
```

### 🧠 Best Practice

Handle **cancellation for async effects**

***

# **9. Derived State Misuse**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  setFullName(first + last);
}, [first, last]);
```

### 🔍 What’s wrong?

Unnecessary state + effect

### 💡 WHY

Derived value doesn’t need effect

### ✅ Fix

```js theme={null}
const fullName = first + last;
```

### 🧠 Best Practice

Avoid effects for **pure computations**

***

# **10. Cleanup Runs Unexpectedly**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  console.log("Mount");

  return () => console.log("Unmount");
}, [count]);
```

### 🔍 What’s wrong?

Cleanup runs on every update, not just unmount.

### 💡 WHY

Cleanup runs before next effect execution

### ✅ Fix

```js theme={null}
useEffect(() => {
  console.log("Mount");

  return () => console.log("Unmount");
}, []);
```

### 🧠 Best Practice

Understand: cleanup runs on **dependency change too**

***

# **11. Strict Mode Double API Call**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  fetchData();
}, []);
```

### 🔍 What’s wrong?

API called twice in development.

### 💡 WHY

Strict Mode double-invokes effects

### ✅ Fix (acceptable pattern)

```js theme={null}
useEffect(() => {
  let ignore = false;

  fetchData().then(data => {
    if (!ignore) setData(data);
  });

  return () => {
    ignore = true;
  };
}, []);
```

### 🧠 Best Practice

Write effects that are **idempotent**

***

# **12. Missing Cleanup in Interval**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  setInterval(fetchData, 5000);
}, []);
```

### 🔍 What’s wrong?

Interval keeps running after unmount

### ✅ Fix

```js theme={null}
useEffect(() => {
  const id = setInterval(fetchData, 5000);
  return () => clearInterval(id);
}, []);
```

***

# **13. Conditional Hook Misuse**

### ❌ Buggy Code

```js theme={null}
if (isLoggedIn) {
  useEffect(() => {
    fetchUser();
  }, []);
}
```

### 🔍 What’s wrong?

Hooks must not be conditional

### 💡 WHY

Breaks React hook ordering

### ✅ Fix

```js theme={null}
useEffect(() => {
  if (isLoggedIn) fetchUser();
}, [isLoggedIn]);
```

***

# **14. Updating State After Unmount**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  fetchData().then(setData);
}, []);
```

### 🔍 What’s wrong?

State update after unmount

### 💡 WHY

Async finishes after component removed

### ✅ Fix

```js theme={null}
useEffect(() => {
  let mounted = true;

  fetchData().then(data => {
    if (mounted) setData(data);
  });

  return () => {
    mounted = false;
  };
}, []);
```

***

# **15. Overloaded Effect**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  fetchData();
  document.title = "Dashboard";
  window.addEventListener("resize", handleResize);
}, []);
```

### 🔍 What’s wrong?

Multiple responsibilities

### 💡 WHY

Hard to maintain/debug

### ✅ Fix

```js theme={null}
useEffect(fetchData, []);

useEffect(() => {
  document.title = "Dashboard";
}, []);

useEffect(() => {
  window.addEventListener("resize", handleResize);
  return () => window.removeEventListener("resize", handleResize);
}, []);
```

***

# **16. Incorrect Dependency (Primitive vs Derived)**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  fetchData(user.id);
}, [user]);
```

### 🔍 What’s wrong?

Effect runs even if only unrelated user fields change

### ✅ Fix

```js theme={null}
}, [user.id]);
```

### 🧠 Best Practice

Depend on **specific values**, not whole objects

***

# **17. useEffect Used for Event Handling**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  if (clicked) {
    submitForm();
  }
}, [clicked]);
```

### 🔍 What’s wrong?

Effect used instead of event handler

### 💡 WHY

Unnecessary indirection

### ✅ Fix

```js theme={null}
const handleClick = () => {
  submitForm();
};
```

***

# **18. Flickering UI due to useEffect Timing**

### ❌ Buggy Code

```js theme={null}
useEffect(() => {
  setHeight(ref.current.offsetHeight);
}, []);
```

### 🔍 What’s wrong?

UI flicker

### 💡 WHY

Effect runs after paint

### ✅ Fix

```js theme={null}
useLayoutEffect(() => {
  setHeight(ref.current.offsetHeight);
}, []);
```

***

# 🚀 Final Takeaway

These bugs test:

* **Mental model of effects**
* **Dependency correctness**
* **Async safety**
* **Performance awareness**

***

# 🧠 `useEffect` — Real-World Machine Coding Problems (Senior Architect Level)

These are **production-grade problems** focused on:

* Side-effect management
* State synchronization
* Performance + correctness

***

# **1. Real-Time Search with Debounce + Cancellation**

## 📌 Requirements

* Input field for search
* Fetch results from API after user stops typing (300–500ms)
* Cancel previous requests if new query starts

## 🎯 UI Behavior

* Loading spinner while fetching
* Results update only for latest query

## 🔄 State / Data Flow

* `query` → debounced value → API call → `results`

## ⚠️ Edge Cases

* Rapid typing
* Empty input
* Slow network

## ⚡ Performance

* Avoid unnecessary API calls
* Avoid race conditions

## 🏗️ Suggested Architecture

* `useDebounce` custom hook
* `useEffect` for API call
* AbortController for cancellation

## 🧩 Solution Approach

1. Track `query`
2. Debounce using `setTimeout` in `useEffect`
3. Trigger API call on debounced value
4. Cancel previous requests in cleanup

***

# **2. Infinite Scroll Feed (Like Social Media)**

## 📌 Requirements

* Load more posts when user scrolls near bottom
* Append new data (pagination)

## 🎯 UI Behavior

* Loader at bottom
* No duplicate requests

## 🔄 Data Flow

* `page` → API → append to `posts`

## ⚠️ Edge Cases

* Fast scrolling
* API failure
* Duplicate triggers

## ⚡ Performance

* Throttle scroll handler
* Avoid multiple fetches

## 🏗️ Architecture

* `IntersectionObserver` OR scroll listener
* `useEffect` tied to `page`

## 🧩 Solution Approach

1. Track `page`
2. Trigger fetch when sentinel visible
3. Append results
4. Cleanup observer

***

# **3. Real-Time Notifications (Polling vs WebSocket)**

## 📌 Requirements

* Fetch notifications every 10 seconds OR use WebSocket

## 🎯 UI Behavior

* Live updates
* Badge count

## 🔄 Data Flow

* Polling interval OR socket subscription → state

## ⚠️ Edge Cases

* Tab inactive
* Multiple subscriptions

## ⚡ Performance

* Avoid redundant polling

## 🏗️ Architecture

* `useEffect` with interval OR socket lifecycle

## 🧩 Solution Approach

1. Start polling/socket in effect
2. Cleanup on unmount
3. Pause when tab inactive (optional)

***

# **4. Form Auto-Save (Draft Feature)**

## 📌 Requirements

* Save form data automatically every few seconds

## 🎯 UI Behavior

* “Saving…” indicator
* “Saved” confirmation

## 🔄 Data Flow

* Form state → debounce → API

## ⚠️ Edge Cases

* Rapid typing
* Network failure

## ⚡ Performance

* Avoid saving on every keystroke

## 🏗️ Architecture

* Debounced `useEffect`
* Retry logic

## 🧩 Solution Approach

1. Watch form state
2. Debounce save call
3. Handle errors + retries

***

# **5. Theme Sync (System + LocalStorage + UI)**

## 📌 Requirements

* Sync theme between:

  * System preference
  * LocalStorage
  * UI

## 🎯 UI Behavior

* Dark/light mode toggle

## 🔄 Data Flow

* System → state → localStorage → DOM

## ⚠️ Edge Cases

* System theme changes
* First load

## ⚡ Performance

* Avoid unnecessary re-renders

## 🏗️ Architecture

* Multiple `useEffect`s for each sync layer

## 🧩 Solution Approach

1. Read localStorage on mount
2. Listen to system changes
3. Update DOM class

***

# **6. Live Chat System (WebSocket Lifecycle)**

## 📌 Requirements

* Connect to WebSocket
* Receive/send messages

## 🎯 UI Behavior

* Real-time chat updates

## 🔄 Data Flow

* Socket → messages state

## ⚠️ Edge Cases

* Reconnect on disconnect
* Cleanup on unmount

## ⚡ Performance

* Avoid multiple connections

## 🏗️ Architecture

* `useEffect` for socket lifecycle

## 🧩 Solution Approach

1. Connect in effect
2. Add listeners
3. Cleanup on unmount

***

# **7. Multi-Tab Sync (LocalStorage Event)**

## 📌 Requirements

* Sync state across browser tabs

## 🎯 UI Behavior

* Changes in one tab reflect in others

## 🔄 Data Flow

* localStorage → storage event → state

## ⚠️ Edge Cases

* Same tab updates don’t trigger event

## 🏗️ Architecture

* `useEffect` for storage listener

## 🧩 Solution Approach

1. Listen to `storage` event
2. Update state accordingly
3. Cleanup listener

***

# **8. Dynamic Script Loader (3rd Party SDK)**

## 📌 Requirements

* Load external script (e.g. payment SDK)
* Initialize only once

## 🎯 UI Behavior

* Show loader until script ready

## ⚠️ Edge Cases

* Script already loaded
* Multiple mounts

## ⚡ Performance

* Avoid duplicate script injection

## 🏗️ Architecture

* Singleton loader + effect

## 🧩 Solution Approach

1. Check if script exists
2. Inject if not
3. Cleanup if needed

***

# **9. Video Player Sync (Play/Pause State)**

## 📌 Requirements

* Sync React state with HTML video player

## 🎯 UI Behavior

* Button controls video playback

## 🔄 Data Flow

* state → DOM API (`video.play()`)

## ⚠️ Edge Cases

* User manually pauses video

## 🏗️ Architecture

* `useRef` + `useEffect`

## 🧩 Solution Approach

1. Store ref
2. Effect reacts to `isPlaying`
3. Call DOM APIs

***

# **10. Data Fetch with Cache Layer**

## 📌 Requirements

* Fetch data but cache results to avoid refetching

## 🎯 UI Behavior

* Instant load for cached data

## 🔄 Data Flow

* cache → state → API fallback

## ⚠️ Edge Cases

* Stale cache

## ⚡ Performance

* Minimize network calls

## 🏗️ Architecture

* In-memory cache or context

## 🧩 Solution Approach

1. Check cache first
2. Fetch if missing
3. Store result

***

# **11. Page Visibility-Based Polling**

## 📌 Requirements

* Pause polling when tab is inactive

## 🎯 UI Behavior

* Resume when user returns

## ⚠️ Edge Cases

* Frequent tab switching

## 🏗️ Architecture

* `visibilitychange` listener

## 🧩 Solution Approach

1. Listen to visibility API
2. Start/stop polling accordingly

***

# **12. Scroll Restoration (SPA Navigation)**

## 📌 Requirements

* Restore scroll position on navigation

## 🎯 UI Behavior

* Return to previous scroll position

## 🔄 Data Flow

* route → scroll position map

## ⚠️ Edge Cases

* Dynamic content height

## 🏗️ Architecture

* `useEffect` + router integration

## 🧩 Solution Approach

1. Save scroll before route change
2. Restore after mount

***

# **13. Analytics Tracker (Page Views + Events)**

## 📌 Requirements

* Track page views + user actions

## 🎯 UI Behavior

* Invisible tracking

## 🔄 Data Flow

* route → analytics API

## ⚠️ Edge Cases

* Duplicate tracking in Strict Mode

## 🏗️ Architecture

* `useEffect` tied to route

## 🧩 Solution Approach

1. Trigger tracking on route change
2. Deduplicate events

***

# 🚀 Final Takeaway

These problems test:

* **Effect orchestration**
* **Async + cleanup mastery**
* **Performance optimization**
* **Architectural thinking**

***

# 🧠 Senior-Level Interview Questions — `useEffect`

These questions are designed to evaluate:

* Deep mental models
* Real-world problem solving
* Trade-offs & debugging ability

***

# **1. When would you deliberately avoid `useEffect` even if side effects seem involved?**

### 🔁 Follow-up

* Can you give an example where removing `useEffect` improved performance?

### ✅ Strong Answer

* Avoid when logic is **derivable during render**
* Example:

```js theme={null}
const fullName = first + last;
```

instead of syncing via effect

* Also avoid when logic belongs in:

  * Event handlers
  * Memoization (`useMemo`)
* Effects should be for **external synchronization only**

### ❌ Weak Answer

> “Whenever possible”

➡️ Fails because it lacks criteria and reasoning

***

# **2. Explain why `useEffect` is considered a synchronization mechanism, not a lifecycle hook**

### 🔁 Follow-up

* How does this mental model change how you write code?

### ✅ Strong Answer

* Lifecycle thinking = “run on mount/update”
* Effect thinking = “keep X in sync with Y”
* Example:

```js theme={null}
useEffect(() => {
  document.title = count;
}, [count]);
```

### ❌ Weak Answer

> “It replaces lifecycle methods”

➡️ Too shallow, no conceptual clarity

***

# **3. How would you debug an effect that runs more times than expected?**

### 🔁 Follow-up

* What tools or techniques would you use?

### ✅ Strong Answer

* Check dependency array
* Log dependency values
* Look for unstable references (functions/objects)
* Use React DevTools Profiler

### ❌ Weak Answer

> “Add console.log”

➡️ Lacks structured debugging approach

***

# **4. Why do stale closures occur, and how do you systematically prevent them?**

### 🔁 Follow-up

* When is adding dependencies NOT the best solution?

### ✅ Strong Answer

* Closure captures values at render time
* Fix:

  * Add dependencies
  * Use functional updates
  * Use refs for mutable values

### ❌ Weak Answer

> “Add it to dependency array”

➡️ Not always correct (can cause loops)

***

# **5. Design a robust data-fetching effect for a rapidly changing parameter (e.g., search)**

### 🔁 Follow-up

* How do you prevent race conditions?

### ✅ Strong Answer

* Debounce input
* Use `AbortController`
* Track latest request

### ❌ Weak Answer

> “Call API in useEffect”

➡️ Ignores real-world issues

***

# **6. Why is putting functions in dependency arrays tricky?**

### 🔁 Follow-up

* When would you NOT use `useCallback`?

### ✅ Strong Answer

* Functions change reference each render
* Causes unnecessary re-runs
* Use `useCallback` only when necessary

### ❌ Weak Answer

> “Because it re-renders”

➡️ Incorrect reasoning

***

# **7. How does React internally schedule effects?**

### 🔁 Follow-up

* What is the order of cleanup vs execution?

### ✅ Strong Answer

* Effects run after commit phase
* Order:

```
Cleanup (prev) → Effect (new)
```

### ❌ Weak Answer

> “After render”

➡️ Incomplete

***

# **8. How would you prevent duplicate API calls in Strict Mode?**

### 🔁 Follow-up

* Should you “fix” this or accept it?

### ✅ Strong Answer

* Make effects idempotent
* Use guards or caching
* Don’t rely on “run once” assumption

### ❌ Weak Answer

> “Disable Strict Mode”

➡️ Bad practice

***

# **9. When would you use `useLayoutEffect` instead of `useEffect`?**

### 🔁 Follow-up

* What is the performance trade-off?

### ✅ Strong Answer

* DOM measurement before paint
* Blocking → affects performance

### ❌ Weak Answer

> “When useEffect doesn’t work”

➡️ No understanding

***

# **10. How do you handle cleanup for async operations?**

### 🔁 Follow-up

* What happens if you don’t?

### ✅ Strong Answer

* AbortController or flags
* Prevent state updates after unmount

### ❌ Weak Answer

> “Use try/catch”

➡️ Not relevant

***

# **11. How would you structure effects in a large component?**

### 🔁 Follow-up

* What’s the downside of a single large effect?

### ✅ Strong Answer

* Split by responsibility
* Easier dependency management

### ❌ Weak Answer

> “Keep everything in one place”

➡️ Poor scalability

***

# **12. What are the trade-offs of heavy `useEffect` usage?**

### 🔁 Follow-up

* What alternatives would you consider?

### ✅ Strong Answer

* Hard to reason about dependencies
* Leads to bugs
* Alternatives:

  * Derived state
  * Event handlers
  * Server-side logic

### ❌ Weak Answer

> “It slows performance”

➡️ Vague

***

# **13. How would you debug a memory leak caused by `useEffect`?**

### 🔁 Follow-up

* What patterns commonly cause leaks?

### ✅ Strong Answer

* Look for missing cleanup
* Event listeners, intervals, subscriptions

### ❌ Weak Answer

> “Check console errors”

➡️ Insufficient

***

# **14. How do dependency arrays impact performance?**

### 🔁 Follow-up

* What happens if you over-specify dependencies?

### ✅ Strong Answer

* Too many dependencies → frequent re-runs
* Too few → stale data

### ❌ Weak Answer

> “They control when effect runs”

➡️ Too basic

***

# **15. Explain a scenario where `useEffect` introduces a bug instead of solving one**

### 🔁 Follow-up

* How would you refactor?

### ✅ Strong Answer

* Derived state example
* Leads to unnecessary renders + bugs

### ❌ Weak Answer

> “When used incorrectly”

➡️ No concrete example

***

# **16. How would you design a custom hook that uses `useEffect` safely?**

### 🔁 Follow-up

* What responsibilities should it hide?

### ✅ Strong Answer

* Encapsulate side effects
* Expose clean API
* Handle cleanup internally

### ❌ Weak Answer

> “Just wrap useEffect”

➡️ Too shallow

***

# **17. What happens if dependencies include objects or arrays?**

### 🔁 Follow-up

* How do you stabilize them?

### ✅ Strong Answer

* Reference changes → re-run
* Use `useMemo`

### ❌ Weak Answer

> “It works fine”

➡️ Incorrect

***

# **18. How would you handle polling with `useEffect` efficiently?**

### 🔁 Follow-up

* How do you pause polling?

### ✅ Strong Answer

* `setInterval` + cleanup
* Pause via visibility API

### ❌ Weak Answer

> “Use setInterval”

➡️ Incomplete

***

# **19. How do you decide whether logic belongs in `useEffect` vs event handler?**

### 🔁 Follow-up

* Give a real-world example

### ✅ Strong Answer

* Event-triggered → handler
* State sync → effect

### ❌ Weak Answer

> “Depends”

➡️ Not actionable

***

# **20. Explain how `useEffect` behaves in concurrent rendering**

### 🔁 Follow-up

* Why must effects be resilient?

### ✅ Strong Answer

* Effects may run multiple times
* Must be idempotent

### ❌ Weak Answer

> “It works same”

➡️ Incorrect

***

# 🚀 Final Insight

A strong candidate:

* Thinks in **synchronization, not lifecycle**
* Avoids unnecessary effects
* Handles **async, cleanup, and dependencies correctly**
* Understands **React internals and trade-offs**

***
