> ## 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.

# Custom hooks

# 📘 Custom Hooks in React — Complete Theory Guide

***

## 1. 📌 Introduction

### 🔹 What are Custom Hooks?

Custom Hooks are **JavaScript functions** that:

* Start with the prefix `use`
* Allow you to **reuse stateful logic** across multiple components

They are built using existing React hooks like:

* `useState`
* `useEffect`
* `useRef`
* etc.

👉 In simple terms:
**Custom hooks = reusable logic extracted from components**

***

### 🔹 Why are Custom Hooks Important?

Without custom hooks:

* Logic gets duplicated across components
* Components become large and harder to maintain

With custom hooks:

* Logic becomes **modular and reusable**
* Components become **clean and focused on UI**

💡 Think of them as:

> “Utility functions for React logic”

***

### 🔹 When and Why Do We Use Them?

Use custom hooks when:

* 🔁 You repeat logic across multiple components
* 🧠 A component has too much logic mixed with UI
* 🧩 You want to separate concerns (logic vs presentation)
* ⚙️ You want to abstract complex behavior (API calls, forms, timers)

#### Example Use Cases:

* Fetching data (`useFetch`)
* Form handling (`useForm`)
* Window resize tracking (`useWindowSize`)
* Authentication (`useAuth`)
* Debouncing input (`useDebounce`)

***

## 2. ⚙️ Concepts / Internal Workings

### 🔹 1. Hooks are Just Functions (But with Rules)

Custom hooks:

* Are plain JavaScript functions
* Can call other hooks
* Must follow **Rules of Hooks**

***

### 🔹 2. Rules of Hooks (Critical)

1. Only call hooks:

   * At the top level (not inside loops/conditions)
2. Only call hooks:

   * Inside React functions (components or custom hooks)

❌ Wrong:

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

✅ Correct:

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

***

### 🔹 3. How Custom Hooks Work Internally

React internally tracks hooks using a **call order system**.

👉 Important idea:

* React does NOT track hooks by name
* It tracks them by **order of execution**

Example:

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

React internally:

```
Hook #1 → useState
Hook #2 → useEffect
```

So:

* If order changes → React breaks ❌
* That’s why hooks must always run in the same order

***

### 🔹 4. Each Hook Has Its Own State

Every time you use a custom hook:

* It creates **independent state instances**

```js theme={null}
const count1 = useCounter();
const count2 = useCounter();
```

👉 These do NOT share state unless explicitly designed to

***

### 🔹 5. Relationship with Other React Features

| Feature      | Relationship                       |
| ------------ | ---------------------------------- |
| `useState`   | Used inside custom hooks for state |
| `useEffect`  | Used for side effects              |
| `useContext` | Share global data                  |
| `useReducer` | Manage complex state               |
| `useRef`     | Store persistent mutable values    |
| Components   | Consume custom hooks               |

👉 Custom hooks are a **composition layer** over these primitives

***

## 3. 🧪 Syntax & Examples

***

### 🔹 Basic Syntax

```js theme={null}
function useCustomHook() {
  // use other hooks
  return something;
}
```

***

### 🔹 Example 1: Counter Hook

```js theme={null}
import { useState } from "react";

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

  const increment = () => setCount(c => c + 1);
  const decrement = () => setCount(c => c - 1);
  const reset = () => setCount(initialValue);

  return { count, increment, decrement, reset };
}
```

#### Usage:

```js theme={null}
function App() {
  const { count, increment } = useCounter(5);

  return <button onClick={increment}>{count}</button>;
}
```

***

### 🔹 Example 2: Fetch Data Hook

```js theme={null}
import { useState, useEffect } from "react";

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    let isMounted = true;

    setLoading(true);

    fetch(url)
      .then(res => res.json())
      .then(data => {
        if (isMounted) {
          setData(data);
          setLoading(false);
        }
      })
      .catch(err => {
        if (isMounted) {
          setError(err);
          setLoading(false);
        }
      });

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

  return { data, loading, error };
}
```

***

### 🔹 Example 3: Window Size Hook

```js theme={null}
import { useState, useEffect } from "react";

function useWindowSize() {
  const [size, setSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight
  });

  useEffect(() => {
    function handleResize() {
      setSize({
        width: window.innerWidth,
        height: window.innerHeight
      });
    }

    window.addEventListener("resize", handleResize);

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

  return size;
}
```

***

### 🔹 Example 4: Debounce Hook

```js theme={null}
import { useState, useEffect } from "react";

function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const id = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => clearTimeout(id);
  }, [value, delay]);

  return debouncedValue;
}
```

***

### 🔹 Example 5: Sharing Logic Across Components

```js theme={null}
function SearchComponent() {
  const debouncedQuery = useDebounce(query, 500);
}

function FilterComponent() {
  const debouncedFilter = useDebounce(filter, 300);
}
```

👉 Same logic, different components → clean reuse

***

## 4. ⚠️ Edge Cases / Common Mistakes

***

### 🔹 1. Breaking Hook Order

❌ Problem:

```js theme={null}
if (condition) {
  useState();
}
```

👉 Leads to:

* Bugs
* State mismatch
* Crashes

***

### 🔹 2. Forgetting Dependencies in `useEffect`

```js theme={null}
useEffect(() => {
  fetchData();
}, []); // ❌ might miss dependencies
```

👉 Leads to stale data or unexpected behavior

***

### 🔹 3. Returning Unstable Functions

```js theme={null}
return {
  increment: () => setCount(count + 1) // ❌ stale closure
};
```

✅ Fix:

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

***

### 🔹 4. Sharing State Accidentally (Wrong Assumption)

```js theme={null}
const a = useCounter();
const b = useCounter();
```

👉 These are independent
Not shared unless you use context

***

### 🔹 5. Memory Leaks (Async + Effects)

```js theme={null}
useEffect(() => {
  fetchData(); // ❌ may update unmounted component
}, []);
```

✅ Fix:

* Use cleanup
* Track mounted state
* Use `AbortController`

***

### 🔹 6. Over-Abstraction

❌ Bad:

* Creating hooks for trivial logic

👉 Leads to:

* Hard-to-read code
* Unnecessary complexity

***

## 5. ✅ Best Practices

***

### 🔹 1. Follow Naming Convention

✔ Must start with `use`

```js theme={null}
useAuth
useFetch
useForm
```

👉 Required for React to recognize hooks

***

### 🔹 2. Keep Hooks Focused

✔ One responsibility per hook

❌ Bad:

```js theme={null}
useEverything()
```

✔ Good:

```js theme={null}
useFetch()
useAuth()
useForm()
```

***

### 🔹 3. Extract Logic, Not UI

❌ Don't:

* Return JSX from hooks

✔ Do:

* Return data and functions only

***

### 🔹 4. Use Functional Updates

Avoid stale state issues:

```js theme={null}
setState(prev => ...)
```

***

### 🔹 5. Optimize Re-renders

Use:

* `useCallback`
* `useMemo`

Inside hooks when needed

***

### 🔹 6. Handle Cleanup Properly

Always clean:

* Event listeners
* Timers
* Subscriptions

```js theme={null}
return () => {
  // cleanup
};
```

***

### 🔹 7. Avoid Side Effects Outside Hooks

❌ Wrong:

```js theme={null}
function useSomething() {
  fetch(); // outside useEffect ❌
}
```

✔ Correct:

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

***

### 🔹 8. Test Custom Hooks

Use libraries like:

* React Testing Library
* Jest

Test:

* State changes
* Side effects

***

### 🔹 9. Document Your Hooks

Especially for teams:

```js theme={null}
/**
 * useFetch - Fetch data from API
 * @param {string} url
 */
```

***

### 🔹 10. Think in Composition

👉 Combine hooks:

```js theme={null}
function useUserData() {
  const { data } = useFetch("/api/user");
  const isOnline = useOnlineStatus();

  return { data, isOnline };
}
```

***

# 🧠 Final Mental Model

* Custom hooks are **logic containers**
* They **compose React hooks**
* They **do not share state unless designed**
* They make your app:

  * Cleaner
  * Reusable
  * Scalable

***

# 🧠 Senior-Level React Interview — Custom Hooks (Conceptual Deep Dive)

***

## 1. What problem do custom hooks actually solve beyond “code reuse”?

### ✅ Strong Answer

Custom hooks are not just about reuse — they solve **separation of concerns at the logic level**.

Before hooks:

* Logic reuse required:

  * HOCs (Higher-Order Components)
  * Render props
* These introduced:

  * Wrapper hell
  * Prop drilling complexity
  * Hard-to-trace data flow

👉 Custom hooks allow:

* Extracting **stateful logic without altering component structure**

```js theme={null}
function useAuth() {
  const [user, setUser] = useState(null);
  // logic
  return user;
}
```

### 💡 Why this matters

* Keeps components focused on UI
* Improves composability
* Eliminates structural overhead (unlike HOCs)

### 🔁 Comparison

| Approach     | Problem             |
| ------------ | ------------------- |
| HOC          | Nested wrappers     |
| Render Props | Callback nesting    |
| Custom Hooks | Flat + composable ✅ |

***

## 2. How does React internally track state for custom hooks?

### ✅ Strong Answer

React does **not treat custom hooks differently**.

Internally:

* React maintains a **linked list of hooks per component**
* Hooks are identified by **call order, not name**

```js theme={null}
useState();   // Hook #1
useEffect();  // Hook #2
```

Custom hook:

```js theme={null}
function useSomething() {
  useState(); // Hook #?
}
```

👉 React **inlines this into the component’s hook list**

### 💡 Why this matters

* Breaking order → corrupts state mapping
* Explains why hooks must:

  * Not be conditional
  * Not be inside loops

***

## 3. Why must custom hooks follow the “use” naming convention?

### ✅ Strong Answer

The `use` prefix is not stylistic — it’s required for:

1. **Linting enforcement** (`eslint-plugin-react-hooks`)
2. Static analysis to ensure:

   * Hooks are called correctly
   * Rules of hooks are followed

👉 React itself doesn’t enforce naming at runtime, but tooling does.

### 💡 Why this matters

Without naming convention:

* Bugs won’t be caught early
* Hook misuse becomes silent

***

## 4. Do multiple components sharing a custom hook share state?

### ✅ Strong Answer

No — **custom hooks do NOT share state by default**.

Each call:

* Creates an independent state instance

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

const a = useCounter();
const b = useCounter();
```

👉 `a` and `b` are completely separate

### 💡 Why

Because:

* State is tied to the component instance
* Not to the hook function

### 🔁 To share state:

Use:

* `useContext`
* External stores (Redux, Zustand)

***

## 5. When should you NOT create a custom hook?

### ✅ Strong Answer

Avoid custom hooks when:

1. Logic is trivial

```js theme={null}
const doubled = count * 2;
```

2. No reuse exists
3. It increases abstraction without clarity

### 💡 Why

Over-abstraction:

* Makes debugging harder
* Reduces readability

👉 Rule:

> Extract only when it improves clarity OR reuse

***

## 6. How do custom hooks affect component re-renders?

### ✅ Strong Answer

Custom hooks **do not change React’s rendering behavior**.

Re-render happens when:

* State changes
* Props change

Inside hook:

```js theme={null}
const [state, setState] = useState();
```

👉 Updating this triggers parent component re-render

### 💡 Important nuance

Returning new objects/functions:

```js theme={null}
return { value }; // new object every render ❌
```

👉 Causes unnecessary re-renders downstream

### ✅ Fix

```js theme={null}
return useMemo(() => ({ value }), [value]);
```

***

## 7. How do you prevent stale closures in custom hooks?

### ✅ Strong Answer

Stale closures occur when:

* Functions capture outdated state

```js theme={null}
const increment = () => setCount(count + 1); // ❌
```

### ✅ Fix: Functional updates

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

### 💡 Why

* Uses latest state snapshot
* Avoids dependency issues

***

## 8. How should side effects be handled inside custom hooks?

### ✅ Strong Answer

Always use `useEffect` (or similar)

❌ Wrong:

```js theme={null}
function useData() {
  fetch("/api"); // side effect outside hook lifecycle ❌
}
```

✅ Correct:

```js theme={null}
useEffect(() => {
  fetch("/api");
}, []);
```

### 💡 Why

* Ensures lifecycle consistency
* Prevents repeated or uncontrolled execution

***

## 9. How do you design a robust data-fetching custom hook?

### ✅ Strong Answer

Key concerns:

* Loading state
* Error handling
* Cancellation
* Dependency control

```js theme={null}
function useFetch(url) {
  const [data, setData] = useState();
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const controller = new AbortController();

    fetch(url, { signal: controller.signal })
      .then(res => res.json())
      .then(setData)
      .catch(err => {
        if (err.name !== "AbortError") throw err;
      });

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

  return { data, loading };
}
```

### 💡 Why

Prevents:

* Memory leaks
* Race conditions

***

## 10. What are the trade-offs between custom hooks and context?

### ✅ Strong Answer

| Aspect        | Custom Hook | Context              |
| ------------- | ----------- | -------------------- |
| State sharing | ❌           | ✅                    |
| Reusability   | ✅           | ⚠️                   |
| Performance   | Better      | Can cause re-renders |
| Scope         | Local       | Global               |

### 💡 Insight

* Custom hook = logic reuse
* Context = state sharing

👉 Often used together

***

## 11. How do you compose multiple custom hooks safely?

### ✅ Strong Answer

Hooks can call other hooks:

```js theme={null}
function useUser() {
  const data = useFetch("/user");
  const isOnline = useOnlineStatus();

  return { data, isOnline };
}
```

### ⚠️ Pitfall

* Order must remain consistent

### 💡 Why

Composition works because:

* React flattens hook calls internally

***

## 12. What are common memory leak scenarios in custom hooks?

### ✅ Strong Answer

1. Async updates after unmount
2. Uncleaned event listeners
3. Timers not cleared

```js theme={null}
useEffect(() => {
  const id = setTimeout(() => {}, 1000);
  return () => clearTimeout(id);
}, []);
```

### 💡 Why

React doesn’t auto-clean side effects

***

## 13. How do you make a custom hook configurable and reusable?

### ✅ Strong Answer

Use parameters:

```js theme={null}
function useDebounce(value, delay = 300) {
```

Return flexible API:

```js theme={null}
return { value, cancel };
```

### 💡 Why

* Makes hook adaptable
* Avoids rewriting logic

***

## 14. When should you use `useReducer` inside a custom hook?

### ✅ Strong Answer

Use when:

* State is complex
* Multiple transitions exist

```js theme={null}
function useForm() {
  const [state, dispatch] = useReducer(reducer, initialState);
}
```

### 💡 Why

* Better state predictability
* Easier debugging

***

## 15. How do custom hooks interact with Suspense and concurrent features?

### ✅ Strong Answer

Custom hooks:

* Can throw promises (for Suspense)
* Must be idempotent (safe to re-run)

### 💡 Why

Concurrent rendering:

* May call hooks multiple times
* Requires side effects to be well-controlled

***

## 16. What’s the risk of returning non-memoized functions from hooks?

### ✅ Strong Answer

```js theme={null}
return { onClick: () => {} };
```

👉 New function every render → breaks memoization

### ✅ Fix

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

### 💡 Why

* Prevents unnecessary child re-renders

***

## 17. How do you debug issues inside custom hooks?

### ✅ Strong Answer

Techniques:

* Add logs inside hook
* Use React DevTools (inspect hooks)
* Break logic into smaller hooks

### 💡 Advanced

React DevTools shows:

* Hook state per component instance

***

## 18. What is a “hook factory” and when would you use it?

### ✅ Strong Answer

A function that returns a custom hook:

```js theme={null}
function createUseFeature(config) {
  return function useFeature() {
    return config;
  };
}
```

### 💡 Use case

* Dynamic behavior
* Multi-tenant apps
* Library design

***

## 🔚 Final Thought

At a senior level, custom hooks are not just about:

* Reuse

They are about:

* **Designing clean abstractions**
* **Managing complexity**
* **Ensuring predictable behavior under React’s rendering model**

***

# 🧠 Senior-Level MCQs — Custom Hooks in React

***

## 1. What happens if a custom hook is called conditionally inside a component?

```js theme={null}
if (isLoggedIn) {
  useAuth();
}
```

### Options:

A. It works fine if condition is stable
B. React throws a runtime error immediately
C. It may cause incorrect state mapping across renders
D. It only breaks in production builds

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

### 💡 Explanation:

React relies on **hook call order**, not names. Conditional calls shift the order, causing:

* State mismatch
* Unexpected bugs

### ❌ Why others are wrong:

* A: Even stable conditions can change → unsafe
* B: React doesn't always throw explicit errors
* D: This issue is environment-independent

***

## 2. What is the real reason custom hooks must start with `use`?

### Options:

A. React runtime uses it to identify hooks
B. Babel transforms functions starting with `use`
C. ESLint uses it to enforce Rules of Hooks
D. It improves performance optimizations

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

### 💡 Explanation:

The `use` prefix enables **static analysis via ESLint**, ensuring:

* Hooks are not used conditionally
* Hooks follow rules

### ❌ Why others are wrong:

* A: React runtime doesn't rely on naming
* B: Babel does not enforce hook behavior
* D: No performance impact

***

## 3. Two components use the same custom hook. Will they share state?

### Options:

A. Yes, always
B. Only if hook uses `useState`
C. No, each call creates independent state
D. Only if wrapped in `useMemo`

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

### 💡 Explanation:

Each invocation creates a **separate state instance** tied to that component.

### ❌ Why others are wrong:

* A: Incorrect assumption
* B: `useState` doesn't share state
* D: `useMemo` doesn’t share state

***

## 4. What is the risk of returning a new object from a custom hook on every render?

```js theme={null}
return { value };
```

### Options:

A. Memory leak
B. Infinite loop
C. Unnecessary re-renders in consuming components
D. Hook order corruption

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

### 💡 Explanation:

New object reference each render → breaks shallow comparison → triggers re-renders.

### ❌ Why others are wrong:

* A: No leak here
* B: No loop unless used incorrectly
* D: Hook order unaffected

***

## 5. What problem does this code introduce?

```js theme={null}
const increment = () => setCount(count + 1);
```

### Options:

A. Memory leak
B. Stale closure
C. Infinite recursion
D. Hook violation

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

### 💡 Explanation:

Function captures outdated `count` → leads to incorrect updates.

### ❌ Why others are wrong:

* A: No leak
* C: No recursion
* D: Hook rules not violated

***

## 6. What is the correct fix for stale closure?

### Options:

A. `setCount(count + 1)`
B. `setCount(prev => prev + 1)`
C. `useMemo(() => count + 1)`
D. `useEffect(() => setCount(count + 1))`

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

### 💡 Explanation:

Functional update ensures latest state is used.

### ❌ Why others are wrong:

* A: Same stale issue
* C: Not updating state
* D: Incorrect pattern

***

## 7. Why is this problematic in a custom hook?

```js theme={null}
fetch("/api/data");
```

(outside `useEffect`)

### Options:

A. Causes memory leak
B. Runs only once
C. Runs on every render causing side effects
D. Breaks hook rules

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

### 💡 Explanation:

Code executes on every render → uncontrolled side effects.

### ❌ Why others are wrong:

* A: Not necessarily
* B: Opposite behavior
* D: Not a hook violation

***

## 8. What happens if a custom hook changes the order of internal hooks dynamically?

### Options:

A. React ignores the change
B. Causes incorrect state association
C. Only affects performance
D. Only affects nested hooks

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

### 💡 Explanation:

React maps hooks by order → mismatch leads to bugs.

### ❌ Why others are wrong:

* A: React doesn't ignore
* C: More than performance
* D: Affects entire hook chain

***

## 9. What is the purpose of `AbortController` in a data-fetching hook?

### Options:

A. Optimize fetch speed
B. Cancel ongoing requests on unmount
C. Retry failed requests
D. Prevent duplicate state updates

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

### 💡 Explanation:

Prevents updating state after component unmount.

### ❌ Why others are wrong:

* A: No speed gain
* C: Not for retries
* D: Not its primary purpose

***

## 10. What is the main trade-off between custom hooks and context?

### Options:

A. Hooks are slower
B. Context cannot share state
C. Hooks don’t share state, context does
D. Context cannot handle side effects

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

### 💡 Explanation:

Custom hooks = logic reuse
Context = shared state

### ❌ Why others are wrong:

* A: No inherent slowness
* B: Context is for sharing
* D: Context can be used with effects

***

## 11. What is a potential issue when returning functions from a custom hook?

### Options:

A. Memory leak
B. New function reference every render
C. Hook rule violation
D. State reset

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

### 💡 Explanation:

New references cause re-renders in dependent components.

### ❌ Why others are wrong:

* A: No leak
* C: Not a rule issue
* D: State unaffected

***

## 12. Why should event listeners be cleaned up in custom hooks?

### Options:

A. Improve performance
B. Avoid duplicate API calls
C. Prevent memory leaks
D. Maintain hook order

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

### 💡 Explanation:

Unremoved listeners persist → memory leaks.

### ❌ Why others are wrong:

* A: Secondary effect
* B: Not directly related
* D: Not relevant

***

## 13. What is wrong with this hook?

```js theme={null}
function useSomething() {
  if (condition) {
    useEffect(() => {});
  }
}
```

### Options:

A. Nothing
B. Violates rules of hooks
C. Causes memory leak
D. Only fails in strict mode

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

### 💡 Explanation:

Hooks must not be conditional.

### ❌ Why others are wrong:

* A: Incorrect
* C: Not necessarily
* D: Fails generally

***

## 14. Why might you use `useReducer` inside a custom hook?

### Options:

A. Improve performance automatically
B. Manage complex state transitions
C. Replace `useEffect`
D. Avoid re-renders

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

### 💡 Explanation:

Better suited for:

* Multiple related state updates
* Complex logic

### ❌ Why others are wrong:

* A: Not guaranteed
* C: Different purpose
* D: Doesn’t prevent re-renders

***

## 15. What happens if you forget dependencies in a custom hook’s `useEffect`?

### Options:

A. Nothing
B. Infinite loop always
C. Stale data or missed updates
D. Hook crash

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

### 💡 Explanation:

Effect won’t react to changes → stale values.

### ❌ Why others are wrong:

* A: Incorrect
* B: Only sometimes
* D: No crash

***

## 16. What is a hook factory?

### Options:

A. Hook that creates components
B. Function returning a custom hook
C. Hook that uses reducers
D. Hook that caches data

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

### 💡 Explanation:

Factory generates customized hooks dynamically.

### ❌ Why others are wrong:

* A: Not definition
* C: Unrelated
* D: Too specific

***

## 17. Why should custom hooks avoid returning JSX?

### Options:

A. Performance issues
B. Violates hook rules
C. Breaks separation of concerns
D. Causes memory leaks

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

### 💡 Explanation:

Hooks should manage logic, not UI.

### ❌ Why others are wrong:

* A: Not primary reason
* B: Not a rule violation
* D: Not related

***

## 18. In concurrent rendering, what must custom hooks ensure?

### Options:

A. They run only once
B. Side effects are idempotent and controlled
C. They don’t use state
D. They avoid `useEffect`

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

### 💡 Explanation:

React may re-run hooks → logic must be safe to repeat.

### ❌ Why others are wrong:

* A: Not guaranteed
* C: Incorrect
* D: Wrong

***

# 🔚 Final Insight

These questions target:

* Internal React behavior
* Subtle bugs
* Real-world design decisions

👉 Mastery here means:
You’re not just using hooks —
You understand how React **thinks under the hood**.

***

# 🧠 Custom Hooks — Real-World Coding Problems (Senior Level)

***

## 1. 🟡 Build `useDebounce` for Search Optimization

### 📌 Problem

Create a hook that delays updating a value until a specified delay has passed.

### Constraints

* Should reset timer on value change
* Must cleanup timers properly

### Expected Behavior

Typing “React” quickly → only final value is returned after delay

### Edge Cases

* Rapid input changes
* Component unmount during delay

### ✅ Solution Explanation

1. Store debounced value in state
2. Use `setTimeout` in `useEffect`
3. Cleanup previous timer

```js theme={null}
function useDebounce(value, delay) {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const id = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(id);
  }, [value, delay]);

  return debounced;
}
```

***

## 2. 🟡 Build `useFetch` with Cancellation

### 📌 Problem

Create a data-fetching hook with loading and error states.

### Constraints

* Prevent state updates after unmount
* Handle errors gracefully

### Expected Behavior

* `loading` true initially
* `data` updates after fetch
* No memory leaks

### Edge Cases

* URL changes quickly
* Network failure

### ✅ Solution Explanation

* Use `AbortController`
* Track loading + error

```js theme={null}
function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const controller = new AbortController();

    fetch(url, { signal: controller.signal })
      .then(res => res.json())
      .then(setData)
      .catch(err => {
        if (err.name !== "AbortError") console.error(err);
      })
      .finally(() => setLoading(false));

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

  return { data, loading };
}
```

***

## 3. 🟡 Build `useLocalStorage`

### 📌 Problem

Sync state with localStorage.

### Constraints

* Persist across reloads
* Sync updates

### Expected Behavior

* Value stored/retrieved from localStorage

### Edge Cases

* Invalid JSON
* Key changes

### ✅ Solution Explanation

```js theme={null}
function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    try {
      return JSON.parse(localStorage.getItem(key)) ?? initialValue;
    } catch {
      return initialValue;
    }
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
}
```

***

## 4. 🟡 Build `useWindowSize`

### 📌 Problem

Track window width and height.

### Constraints

* Must cleanup listeners

### Expected Behavior

Updates on resize

### Edge Cases

* SSR (window undefined)

### ✅ Solution

```js theme={null}
function useWindowSize() {
  const [size, setSize] = useState({ width: 0, height: 0 });

  useEffect(() => {
    function update() {
      setSize({ width: window.innerWidth, height: window.innerHeight });
    }

    update();
    window.addEventListener("resize", update);

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

  return size;
}
```

***

## 5. 🟡 Build `useToggle`

### 📌 Problem

Toggle boolean state with utility functions

### Expected Behavior

* Toggle, setTrue, setFalse

### Edge Cases

* Multiple toggles quickly

### ✅ Solution

```js theme={null}
function useToggle(initial = false) {
  const [state, setState] = useState(initial);

  const toggle = () => setState(s => !s);
  const setTrue = () => setState(true);
  const setFalse = () => setState(false);

  return { state, toggle, setTrue, setFalse };
}
```

***

## 6. 🟠 Build `usePrevious`

### 📌 Problem

Store previous value of a variable

### Expected Behavior

Returns previous render value

### Edge Cases

* First render → undefined

### ✅ Solution

```js theme={null}
function usePrevious(value) {
  const ref = useRef();

  useEffect(() => {
    ref.current = value;
  });

  return ref.current;
}
```

***

## 7. 🟠 Build `useOutsideClick`

### 📌 Problem

Detect clicks outside a component

### Constraints

* Use refs

### Edge Cases

* Multiple components using it

### ✅ Solution

```js theme={null}
function useOutsideClick(ref, callback) {
  useEffect(() => {
    function handleClick(e) {
      if (!ref.current?.contains(e.target)) {
        callback();
      }
    }

    document.addEventListener("click", handleClick);
    return () => document.removeEventListener("click", handleClick);
  }, [ref, callback]);
}
```

***

## 8. 🟠 Build `useOnlineStatus`

### 📌 Problem

Track online/offline state

### Expected Behavior

* Updates on network change

### Edge Cases

* Browser support

### ✅ Solution

```js theme={null}
function useOnlineStatus() {
  const [online, setOnline] = useState(navigator.onLine);

  useEffect(() => {
    const on = () => setOnline(true);
    const off = () => setOnline(false);

    window.addEventListener("online", on);
    window.addEventListener("offline", off);

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

  return online;
}
```

***

## 9. 🔴 Build `useThrottle`

### 📌 Problem

Limit function execution frequency

### Constraints

* Should execute immediately then throttle

### Edge Cases

* Rapid calls

### ✅ Solution

```js theme={null}
function useThrottle(value, delay) {
  const [throttled, setThrottled] = useState(value);
  const lastRun = useRef(Date.now());

  useEffect(() => {
    const now = Date.now();
    if (now - lastRun.current >= delay) {
      setThrottled(value);
      lastRun.current = now;
    }
  }, [value, delay]);

  return throttled;
}
```

***

## 10. 🔴 Build `useIntersectionObserver`

### 📌 Problem

Detect if element is visible in viewport

### Constraints

* Use IntersectionObserver API

### Edge Cases

* Browser fallback

### ✅ Solution

```js theme={null}
function useIntersection(ref) {
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      setVisible(entry.isIntersecting);
    });

    if (ref.current) observer.observe(ref.current);

    return () => observer.disconnect();
  }, [ref]);

  return visible;
}
```

***

## 11. 🔴 Build `useForm` (Reducer-based)

### 📌 Problem

Manage complex form state

### Constraints

* Handle multiple fields

### Edge Cases

* Reset form

### ✅ Solution

```js theme={null}
function useForm(initialState) {
  const reducer = (state, action) => {
    switch (action.type) {
      case "CHANGE":
        return { ...state, [action.name]: action.value };
      case "RESET":
        return initialState;
      default:
        return state;
    }
  };

  const [state, dispatch] = useReducer(reducer, initialState);

  return {
    state,
    handleChange: e =>
      dispatch({ type: "CHANGE", name: e.target.name, value: e.target.value }),
    reset: () => dispatch({ type: "RESET" })
  };
}
```

***

## 12. 🔴 Build `useAsync`

### 📌 Problem

Handle async function lifecycle

### Expected Behavior

* loading, error, result

### Edge Cases

* Multiple calls overlap

### ✅ Solution

```js theme={null}
function useAsync(fn) {
  const [state, setState] = useState({ loading: false });

  const run = async (...args) => {
    setState({ loading: true });
    try {
      const result = await fn(...args);
      setState({ loading: false, result });
    } catch (error) {
      setState({ loading: false, error });
    }
  };

  return { ...state, run };
}
```

***

## 13. 🔴 Build `useEventListener`

### 📌 Problem

Generic event listener hook

### Constraints

* Support dynamic target

### Edge Cases

* Changing handler

### ✅ Solution

```js theme={null}
function useEventListener(event, handler, target = window) {
  useEffect(() => {
    target.addEventListener(event, handler);
    return () => target.removeEventListener(event, handler);
  }, [event, handler, target]);
}
```

***

## 14. 🔴 Build `useClipboard`

### 📌 Problem

Copy text to clipboard

### Expected Behavior

Returns copy function + success state

### Edge Cases

* Permission denied

### ✅ Solution

```js theme={null}
function useClipboard() {
  const [copied, setCopied] = useState(false);

  const copy = async text => {
    try {
      await navigator.clipboard.writeText(text);
      setCopied(true);
    } catch {
      setCopied(false);
    }
  };

  return { copied, copy };
}
```

***

## 15. 🔴 Build `useIdle`

### 📌 Problem

Detect user inactivity

### Constraints

* Reset timer on activity

### Edge Cases

* Multiple event listeners

### ✅ Solution

```js theme={null}
function useIdle(timeout = 3000) {
  const [idle, setIdle] = useState(false);

  useEffect(() => {
    let timer;

    const reset = () => {
      clearTimeout(timer);
      setIdle(false);
      timer = setTimeout(() => setIdle(true), timeout);
    };

    window.addEventListener("mousemove", reset);
    window.addEventListener("keydown", reset);

    reset();

    return () => {
      window.removeEventListener("mousemove", reset);
      window.removeEventListener("keydown", reset);
    };
  }, [timeout]);

  return idle;
}
```

***

## 16. 🔴 Build `useUndoRedo`

### 📌 Problem

Implement undo/redo functionality

### Constraints

* Maintain history stack

### Edge Cases

* Limit history size

### ✅ Solution

```js theme={null}
function useUndoRedo(initial) {
  const [history, setHistory] = useState([initial]);
  const [index, setIndex] = useState(0);

  const set = value => {
    const newHistory = history.slice(0, index + 1);
    newHistory.push(value);
    setHistory(newHistory);
    setIndex(newHistory.length - 1);
  };

  return {
    state: history[index],
    set,
    undo: () => index > 0 && setIndex(i => i - 1),
    redo: () => index < history.length - 1 && setIndex(i => i + 1)
  };
}
```

***

## 17. 🔴 Build `usePagination`

### 📌 Problem

Handle paginated data

### Constraints

* Page navigation

### Edge Cases

* Out-of-bound pages

### ✅ Solution

```js theme={null}
function usePagination(data, perPage) {
  const [page, setPage] = useState(1);

  const max = Math.ceil(data.length / perPage);

  const current = data.slice((page - 1) * perPage, page * perPage);

  return {
    current,
    next: () => setPage(p => Math.min(p + 1, max)),
    prev: () => setPage(p => Math.max(p - 1, 1))
  };
}
```

***

## 18. 🔴 Build `useHover`

### 📌 Problem

Detect hover state

### Edge Cases

* Mobile devices

### ✅ Solution

```js theme={null}
function useHover() {
  const [hovered, setHovered] = useState(false);

  const ref = useRef();

  useEffect(() => {
    const node = ref.current;
    if (!node) return;

    const enter = () => setHovered(true);
    const leave = () => setHovered(false);

    node.addEventListener("mouseenter", enter);
    node.addEventListener("mouseleave", leave);

    return () => {
      node.removeEventListener("mouseenter", enter);
      node.removeEventListener("mouseleave", leave);
    };
  }, []);

  return [ref, hovered];
}
```

***

# 🔚 Final Insight

These problems test:

* Real-world thinking
* Lifecycle awareness
* Cleanup discipline
* Performance considerations

👉 Mastery means:
You can **design hooks like a library author**, not just use them.

***

# 🛠️ Senior React Code Review — Custom Hooks Debugging Challenges

***

## 1. ❗ Stale Closure in Counter Hook

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

  const increment = () => {
    setCount(count + 1);
  };

  return { count, increment };
}
```

### 🔍 What’s wrong?

`increment` uses a **stale value of `count`**

### 💡 Why it happens

Closures capture the value at render time. Multiple rapid updates may use outdated `count`.

### ✅ Fix

```js theme={null}
const increment = () => {
  setCount(c => c + 1);
};
```

### 🧠 Best Practice

Always use **functional updates** when new state depends on previous state.

***

## 2. ❗ Memory Leak in Fetch Hook

```js theme={null}
function useFetch(url) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(setData);
  }, [url]);

  return data;
}
```

### 🔍 What’s wrong?

State may update after component unmounts.

### 💡 Why

Fetch is async; component may unmount before it completes.

### ✅ Fix

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

  fetch(url, { signal: controller.signal })
    .then(res => res.json())
    .then(setData)
    .catch(err => {
      if (err.name !== "AbortError") throw err;
    });

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

### 🧠 Best Practice

Always **cancel async operations** in effects.

***

## 3. ❗ Missing Dependency Causing Stale Data

```js theme={null}
function useSearch(query) {
  const [results, setResults] = useState([]);

  useEffect(() => {
    fetch(`/api?q=${query}`).then(res => res.json()).then(setResults);
  }, []); // ❌

  return results;
}
```

### 🔍 What’s wrong?

Effect does not re-run when `query` changes.

### 💡 Why

Empty dependency array freezes the initial `query`.

### ✅ Fix

```js theme={null}
useEffect(() => {
  fetch(`/api?q=${query}`)
    .then(res => res.json())
    .then(setResults);
}, [query]);
```

### 🧠 Best Practice

Always include **all external dependencies**.

***

## 4. ❗ Event Listener Re-Attached Every Render

```js theme={null}
function useResize(handler) {
  useEffect(() => {
    window.addEventListener("resize", handler);
    return () => window.removeEventListener("resize", handler);
  });
}
```

### 🔍 What’s wrong?

Effect runs on every render → repeated add/remove.

### 💡 Why

No dependency array → runs after every render.

### ✅ Fix

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

### 🧠 Best Practice

Always define **effect dependencies explicitly**.

***

## 5. ❗ Infinite Loop in Hook

```js theme={null}
function useData(url) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url).then(res => res.json()).then(setData);
  }, [data]); // ❌

  return data;
}
```

### 🔍 What’s wrong?

Effect depends on `data`, which it updates → infinite loop.

### 💡 Why

State update triggers effect again.

### ✅ Fix

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

### 🧠 Best Practice

Dependencies should reflect **inputs, not outputs**.

***

## 6. ❗ Unstable Function Causing Re-Renders

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

  return {
    increment: () => setCount(c => c + 1)
  };
}
```

### 🔍 What’s wrong?

New function instance on every render.

### 💡 Why

Functions are recreated → breaks memoization.

### ✅ Fix

```js theme={null}
const increment = useCallback(() => {
  setCount(c => c + 1);
}, []);

return { increment };
```

### 🧠 Best Practice

Memoize functions when passed to children.

***

## 7. ❗ Incorrect Ref Usage

```js theme={null}
function usePrevious(value) {
  const ref = useRef(value);

  return ref.current;
}
```

### 🔍 What’s wrong?

Ref is never updated.

### 💡 Why

`useRef` doesn’t auto-update like state.

### ✅ Fix

```js theme={null}
useEffect(() => {
  ref.current = value;
});
```

### 🧠 Best Practice

Update refs inside effects.

***

## 8. ❗ Breaking Hook Rules

```js theme={null}
function useFeature(flag) {
  if (flag) {
    useEffect(() => {
      console.log("Enabled");
    }, []);
  }
}
```

### 🔍 What’s wrong?

Hook is conditionally called.

### 💡 Why

Breaks hook order → undefined behavior.

### ✅ Fix

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

### 🧠 Best Practice

Never call hooks conditionally.

***

## 9. ❗ Race Condition in Fetch

```js theme={null}
function useUser(id) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch(`/user/${id}`).then(res => res.json()).then(setUser);
  }, [id]);
}
```

### 🔍 What’s wrong?

Older request may overwrite newer one.

### 💡 Why

Async responses return out of order.

### ✅ Fix

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

  fetch(`/user/${id}`)
    .then(res => res.json())
    .then(data => {
      if (active) setUser(data);
    });

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

### 🧠 Best Practice

Handle **race conditions in async hooks**.

***

## 10. ❗ Derived State Stored Incorrectly

```js theme={null}
function useFullName(first, last) {
  const [fullName, setFullName] = useState("");

  useEffect(() => {
    setFullName(first + " " + last);
  }, [first, last]);

  return fullName;
}
```

### 🔍 What’s wrong?

Derived state stored unnecessarily.

### 💡 Why

Adds extra render cycle.

### ✅ Fix

```js theme={null}
return `${first} ${last}`;
```

### 🧠 Best Practice

Avoid storing **derived state**.

***

## 11. ❗ Missing Cleanup for Timer

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

### 🔍 What’s wrong?

Interval never cleared.

### 💡 Why

Leads to memory leaks.

### ✅ Fix

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

### 🧠 Best Practice

Always cleanup timers.

***

## 12. ❗ Using State Instead of Ref for Mutable Value

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

  setCount(c => c + 1);

  return count;
}
```

### 🔍 What’s wrong?

State update inside render → infinite loop.

### 💡 Why

State updates trigger re-render immediately.

### ✅ Fix

```js theme={null}
const ref = useRef(0);
ref.current++;
return ref.current;
```

### 🧠 Best Practice

Use `useRef` for non-render-triggering values.

***

## 13. ❗ Over-Fetching Due to Object Dependency

```js theme={null}
function useFilter(data, filter) {
  useEffect(() => {
    // expensive logic
  }, [filter]);
}
```

### 🔍 What’s wrong?

`filter` is an object → new reference each render.

### 💡 Why

Triggers unnecessary effect runs.

### ✅ Fix

```js theme={null}
const stableFilter = useMemo(() => filter, [JSON.stringify(filter)]);
```

### 🧠 Best Practice

Stabilize object dependencies.

***

## 14. ❗ Hook Not SSR Safe

```js theme={null}
function useWidth() {
  return window.innerWidth;
}
```

### 🔍 What’s wrong?

Breaks in SSR (window undefined).

### 💡 Why

Server doesn’t have `window`.

### ✅ Fix

```js theme={null}
const [width, setWidth] = useState(
  typeof window !== "undefined" ? window.innerWidth : 0
);
```

### 🧠 Best Practice

Guard browser APIs in hooks.

***

## 15. ❗ Incorrect Dependency on Function

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

### 🔍 What’s wrong?

Effect runs every render if `fn` is unstable.

### 💡 Why

Functions are recreated unless memoized.

### ✅ Fix

* Either memoize `fn` in parent OR
* Remove from deps if safe

### 🧠 Best Practice

Stabilize callbacks using `useCallback`.

***

## 16. ❗ State Reset on Key Change

```js theme={null}
function useKeyedState(key) {
  const [value, setValue] = useState(0);
  return [value, setValue];
}
```

### 🔍 What’s wrong?

State does not reset when `key` changes.

### 💡 Why

`useState` only initializes once.

### ✅ Fix

```js theme={null}
useEffect(() => {
  setValue(0);
}, [key]);
```

### 🧠 Best Practice

Handle **prop-driven resets explicitly**.

***

## 17. ❗ Multiple Event Listeners Leak

```js theme={null}
function useScroll() {
  useEffect(() => {
    window.addEventListener("scroll", () => console.log("scroll"));
  }, []);
}
```

### 🔍 What’s wrong?

Anonymous function cannot be removed.

### 💡 Why

Cleanup needs same reference.

### ✅ Fix

```js theme={null}
useEffect(() => {
  const handler = () => console.log("scroll");
  window.addEventListener("scroll", handler);
  return () => window.removeEventListener("scroll", handler);
}, []);
```

### 🧠 Best Practice

Always store handler references.

***

# 🔚 Final Takeaway

These bugs reflect **real production failures**:

* Stale closures
* Race conditions
* Memory leaks
* Dependency mistakes

👉 Senior-level skill =
Not just writing hooks, but **predicting React behavior under pressure**.

***

# 🧠 Senior Frontend Architect — Custom Hooks Machine Coding Problems

***

## 1. 🔴 Build a **Production-Grade Search with Debounce + Caching**

### 📌 Requirements

* Input box with live search
* API call after user stops typing (debounce)
* Cache previous results (avoid duplicate API calls)

### 🖥️ UI Behavior

* Typing → loading spinner
* Cached results → instant display
* Empty query → no API call

### 🔄 State/Data Flow

* `query` → debounced → fetch → cache → render

### ⚠️ Edge Cases

* Rapid typing
* Same query repeated
* API failure

### ⚡ Performance

* Debounce (300–500ms)
* Cache results (Map or object)

### 🏗️ Suggested Architecture

* `useDebounce(query)`
* `useSearch(query)` (handles caching + API)

### 🪜 Solution Approach

1. Create debounce hook
2. Maintain cache with `useRef`
3. Fetch only if query not cached
4. Handle loading + error states

***

## 2. 🔴 Build a **Dynamic Form Builder (Schema-Driven)**

### 📌 Requirements

* Render form based on JSON schema
* Support validation & dynamic fields

### 🖥️ UI Behavior

* Fields appear/disappear based on conditions
* Show validation errors on submit

### 🔄 State/Data Flow

* Schema → generate fields → state via reducer

### ⚠️ Edge Cases

* Nested fields
* Dynamic validation rules
* Reset form

### ⚡ Performance

* Avoid re-rendering all fields
* Memoize field components

### 🏗️ Architecture

* `useForm(schema)`
* `useField(name)`
* `useValidation()`

### 🪜 Approach

1. Use `useReducer` for form state
2. Store schema separately
3. Generate fields dynamically
4. Validate on change/submit

***

## 3. 🔴 Build **Infinite Scroll with Virtualization**

### 📌 Requirements

* Load items as user scrolls
* Render only visible items

### 🖥️ UI Behavior

* Scroll → fetch next page
* Smooth scrolling

### 🔄 State/Data Flow

* Scroll position → trigger fetch → append data

### ⚠️ Edge Cases

* Fast scrolling
* Duplicate fetches
* End of list

### ⚡ Performance

* Virtualize list (windowing)
* Throttle scroll events

### 🏗️ Architecture

* `useInfiniteScroll()`
* `useVirtualList()`

### 🪜 Approach

1. Track scroll position
2. Trigger fetch near bottom
3. Use refs for container height
4. Render subset of items

***

## 4. 🔴 Build **Global Auth System with Custom Hook**

### 📌 Requirements

* Login/logout
* Persist user session
* Protect routes

### 🖥️ UI Behavior

* Redirect unauthenticated users
* Show user info globally

### 🔄 State/Data Flow

* Auth state → context → components

### ⚠️ Edge Cases

* Token expiry
* Refresh token logic

### ⚡ Performance

* Avoid unnecessary re-renders

### 🏗️ Architecture

* `useAuth()` + Context
* `useProtectedRoute()`

### 🪜 Approach

1. Store token in localStorage
2. Sync with context
3. Handle login/logout actions
4. Add route guard hook

***

## 5. 🔴 Build **Real-Time Chat Hook (WebSocket)**

### 📌 Requirements

* Send/receive messages in real-time

### 🖥️ UI Behavior

* Messages update instantly
* Connection status indicator

### 🔄 State/Data Flow

* WebSocket → message stream → UI

### ⚠️ Edge Cases

* Connection drops
* Message ordering

### ⚡ Performance

* Batch updates if needed

### 🏗️ Architecture

* `useWebSocket(url)`
* `useChat(roomId)`

### 🪜 Approach

1. Initialize socket in hook
2. Listen for messages
3. Update state safely
4. Cleanup on unmount

***

## 6. 🔴 Build **Undo/Redo Editor System**

### 📌 Requirements

* Track history of user actions
* Undo/redo support

### 🖥️ UI Behavior

* Undo button reverts state
* Redo reapplies changes

### 🔄 State/Data Flow

* Current state + history stack

### ⚠️ Edge Cases

* Limit history size
* Rapid updates

### ⚡ Performance

* Avoid large memory usage

### 🏗️ Architecture

* `useUndoRedo()`

### 🪜 Approach

1. Maintain history array
2. Track pointer index
3. Slice history on new action
4. Implement undo/redo safely

***

## 7. 🔴 Build **Advanced Data Fetching Hook (React Query Lite)**

### 📌 Requirements

* Cache API responses
* Background refetch
* Deduplicate requests

### 🖥️ UI Behavior

* Instant cached data
* Refetch indicator

### 🔄 State/Data Flow

* Query key → cache → fetch

### ⚠️ Edge Cases

* Stale data
* Parallel requests

### ⚡ Performance

* Cache + deduplication

### 🏗️ Architecture

* `useQuery(key, fetchFn)`
* Global cache store

### 🪜 Approach

1. Use Map for cache
2. Track in-flight requests
3. Return cached data immediately
4. Refetch in background

***

## 8. 🔴 Build **Drag-and-Drop Hook**

### 📌 Requirements

* Drag items between lists

### 🖥️ UI Behavior

* Visual feedback while dragging

### 🔄 State/Data Flow

* Drag state → drop target → update list

### ⚠️ Edge Cases

* Dropping outside
* Reordering

### ⚡ Performance

* Avoid excessive re-renders

### 🏗️ Architecture

* `useDrag()`
* `useDrop()`

### 🪜 Approach

1. Track dragged item with ref
2. Handle drag events
3. Update state on drop
4. Cleanup listeners

***

## 9. 🔴 Build **Feature Flag System**

### 📌 Requirements

* Enable/disable features dynamically

### 🖥️ UI Behavior

* Features toggle without reload

### 🔄 State/Data Flow

* Flags → hook → components

### ⚠️ Edge Cases

* Async flag loading
* Fallback values

### ⚡ Performance

* Avoid re-rendering entire app

### 🏗️ Architecture

* `useFeatureFlag(flagName)`

### 🪜 Approach

1. Store flags globally
2. Fetch from API
3. Provide via context
4. Hook reads specific flag

***

## 10. 🔴 Build **Viewport-Based Lazy Loading System**

### 📌 Requirements

* Load images/components only when visible

### 🖥️ UI Behavior

* Placeholder → load on scroll into view

### 🔄 State/Data Flow

* Intersection → load trigger → render

### ⚠️ Edge Cases

* Fast scroll
* Multiple elements

### ⚡ Performance

* Use IntersectionObserver

### 🏗️ Architecture

* `useInView(ref)`
* `useLazyLoad()`

### 🪜 Approach

1. Observe element visibility
2. Trigger load when visible
3. Unobserve after load
4. Cache loaded state

***

# 🔚 Final Insight

These problems simulate:

* Real product features
* Performance-critical systems
* Scalable architecture design

👉 At senior level, evaluation focuses on:

* Hook design quality
* State management clarity
* Edge-case handling
* Performance awareness

***

# 🧠 Senior Frontend Interview — Custom Hooks (Deep Dive)

***

## 1. How would you decide whether to extract logic into a custom hook vs keeping it inside a component?

### 🔍 Follow-up:

* What signals indicate over-abstraction?
* How does team size affect this decision?

### ✅ Strong Answer:

* Extract when:

  * Logic is reused across components
  * Component becomes too complex (logic/UI mixed)
* Avoid when:

  * Logic is trivial or used once
* Consider:

  * Readability vs reuse trade-off
  * Debuggability

### ❌ Weak Answer:

> “Whenever there is duplicate code”

👉 Fails because:

* Ignores complexity, readability, and maintainability trade-offs

***

## 2. Explain how React tracks hook state internally and why order matters.

### 🔍 Follow-up:

* What happens if order changes?
* Can React detect this reliably?

### ✅ Strong Answer:

* React uses a **linked list of hooks per component**
* Hooks are mapped by **call order**
* Changing order → state mismatch → bugs

### ❌ Weak Answer:

> “React uses hook names”

👉 Fails because:

* Completely incorrect mental model

***

## 3. Design a `useFetch` hook for production use. What concerns would you handle?

### 🔍 Follow-up:

* How do you prevent race conditions?
* How do you cache results?

### ✅ Strong Answer:

Must include:

* Loading/error state
* AbortController (cleanup)
* Race condition handling
* Optional caching layer
* Dependency management

### ❌ Weak Answer:

> “Just use useEffect and fetch”

👉 Fails because:

* Ignores real-world issues like cancellation and caching

***

## 4. Why don’t custom hooks share state across components?

### 🔍 Follow-up:

* How would you make them share state?

### ✅ Strong Answer:

* State is tied to **component instance**
* Each hook call creates a new state
* Share via:

  * Context
  * External store

### ❌ Weak Answer:

> “Because hooks are isolated”

👉 Fails because:

* Doesn’t explain underlying reason

***

## 5. You notice a custom hook causing excessive re-renders. How would you debug it?

### 🔍 Follow-up:

* What tools would you use?
* What patterns cause this?

### ✅ Strong Answer:

Steps:

1. Check returned values (new objects/functions)
2. Inspect dependencies
3. Use React DevTools profiler
4. Add memoization (`useMemo`, `useCallback`)

### ❌ Weak Answer:

> “Use memo everywhere”

👉 Fails because:

* Blind optimization without diagnosis

***

## 6. What are common pitfalls when using `useEffect` inside custom hooks?

### 🔍 Follow-up:

* How do you avoid stale closures?

### ✅ Strong Answer:

* Missing dependencies → stale data
* Over-dependencies → unnecessary runs
* Async side effects → memory leaks
* Fix:

  * Dependency discipline
  * Cleanup functions
  * Functional updates

### ❌ Weak Answer:

> “Just follow ESLint”

👉 Fails because:

* Doesn’t explain reasoning

***

## 7. How would you design a custom hook that is both flexible and reusable?

### 🔍 Follow-up:

* How do you design its API?

### ✅ Strong Answer:

* Accept parameters for configuration
* Return minimal but useful API
* Avoid tight coupling
* Example:

```js theme={null}
useDebounce(value, delay)
```

### ❌ Weak Answer:

> “Make it generic”

👉 Fails because:

* Too vague, no implementation thinking

***

## 8. Explain a scenario where a custom hook introduces a bug due to stale closures.

### 🔍 Follow-up:

* How do you fix it?

### ✅ Strong Answer:

* Event handlers capturing old state
* Fix with:

  * Functional updates
  * Correct dependencies

### ❌ Weak Answer:

> “Closures are tricky”

👉 Fails because:

* No concrete understanding

***

## 9. When would you use `useReducer` inside a custom hook?

### 🔍 Follow-up:

* Why not just use `useState`?

### ✅ Strong Answer:

* Complex state transitions
* Multiple related states
* Better predictability

### ❌ Weak Answer:

> “For big state”

👉 Fails because:

* Lacks clarity on *why*

***

## 10. How do you handle race conditions in async hooks?

### 🔍 Follow-up:

* What if requests return out of order?

### ✅ Strong Answer:

* Use:

  * AbortController OR
  * “isActive” flag
* Ensure only latest request updates state

### ❌ Weak Answer:

> “Use try/catch”

👉 Fails because:

* Doesn’t solve race conditions

***

## 11. What are the trade-offs between custom hooks and third-party libraries like React Query?

### 🔍 Follow-up:

* When would you build vs buy?

### ✅ Strong Answer:

* Custom hooks:

  * Lightweight, flexible
  * Require maintenance
* Libraries:

  * Feature-rich (caching, retries)
  * More abstraction

### ❌ Weak Answer:

> “Libraries are always better”

👉 Fails because:

* Ignores trade-offs

***

## 12. How would you design a hook that works in SSR?

### 🔍 Follow-up:

* What breaks in SSR?

### ✅ Strong Answer:

* Avoid direct browser APIs
* Use guards:

```js theme={null}
typeof window !== "undefined"
```

### ❌ Weak Answer:

> “SSR just works”

👉 Fails because:

* Ignores environment differences

***

## 13. How do you prevent memory leaks in custom hooks?

### 🔍 Follow-up:

* Examples?

### ✅ Strong Answer:

* Cleanup:

  * Event listeners
  * Timers
  * Async calls

### ❌ Weak Answer:

> “React handles cleanup”

👉 Fails because:

* Incorrect assumption

***

## 14. How do custom hooks behave in concurrent rendering?

### 🔍 Follow-up:

* What changes compared to legacy rendering?

### ✅ Strong Answer:

* Hooks may run multiple times
* Must be:

  * Idempotent
  * Side-effect safe

### ❌ Weak Answer:

> “No difference”

👉 Fails because:

* Misses modern React behavior

***

## 15. How would you design a `useQuery`-like hook?

### 🔍 Follow-up:

* How do you cache and deduplicate?

### ✅ Strong Answer:

* Use:

  * Cache map
  * In-flight request tracking
  * Background refetch

### ❌ Weak Answer:

> “Call fetch and store data”

👉 Fails because:

* Misses system-level thinking

***

## 16. What’s the risk of returning non-memoized values from hooks?

### 🔍 Follow-up:

* When is it acceptable?

### ✅ Strong Answer:

* Causes re-renders
* Acceptable if:

  * Not passed to children
  * No performance concern

### ❌ Weak Answer:

> “Always memoize”

👉 Fails because:

* Over-optimization mindset

***

## 17. How would you debug a hook that works locally but fails in production?

### 🔍 Follow-up:

* What differences matter?

### ✅ Strong Answer:

* Check:

  * Strict mode double render
  * Environment differences
  * Race conditions
  * Minification issues

### ❌ Weak Answer:

> “Console.log”

👉 Fails because:

* Too shallow

***

## 18. How do you compose multiple hooks safely?

### 🔍 Follow-up:

* What risks exist?

### ✅ Strong Answer:

* Call hooks in consistent order
* Avoid conditional composition
* Combine outputs cleanly

### ❌ Weak Answer:

> “Just call them”

👉 Fails because:

* Ignores rules of hooks

***

## 19. When can a custom hook hurt performance?

### 🔍 Follow-up:

* Real examples?

### ✅ Strong Answer:

* Frequent re-renders
* Expensive computations inside hook
* Unstable dependencies

### ❌ Weak Answer:

> “Hooks are fast”

👉 Fails because:

* Oversimplified

***

## 🔚 Final Insight

At senior level, interviewers evaluate:

* **Mental model of React internals**
* **Ability to design scalable abstractions**
* **Understanding of trade-offs**
* **Debugging under real-world constraints**

👉 Strong candidates don’t just *use* hooks —
They **design, analyze, and optimize them like systems**.

***
