π 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
useStateuseEffectuseRef- etc.
πΉ Why are Custom Hooks Important?
Without custom hooks:- Logic gets duplicated across components
- Components become large and harder to maintain
- Logic becomes modular and reusable
- Components become clean and focused on UI
β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)
-
Only call hooks:
- At the top level (not inside loops/conditions)
-
Only call hooks:
- Inside React functions (components or custom hooks)
πΉ 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
- 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
πΉ 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 |
3. π§ͺ Syntax & Examples
πΉ Basic Syntax
πΉ Example 1: Counter Hook
Usage:
πΉ Example 2: Fetch Data Hook
πΉ Example 3: Window Size Hook
πΉ Example 4: Debounce Hook
πΉ Example 5: Sharing Logic Across Components
4. β οΈ Edge Cases / Common Mistakes
πΉ 1. Breaking Hook Order
β Problem:- Bugs
- State mismatch
- Crashes
πΉ 2. Forgetting Dependencies in useEffect
πΉ 3. Returning Unstable Functions
πΉ 4. Sharing State Accidentally (Wrong Assumption)
πΉ 5. Memory Leaks (Async + Effects)
- Use cleanup
- Track mounted state
- Use
AbortController
πΉ 6. Over-Abstraction
β Bad:- Creating hooks for trivial logic
- Hard-to-read code
- Unnecessary complexity
5. β Best Practices
πΉ 1. Follow Naming Convention
β Must start withuse
πΉ 2. Keep Hooks Focused
β One responsibility per hook β Bad:πΉ 3. Extract Logic, Not UI
β Donβt:- Return JSX from hooks
- Return data and functions only
πΉ 4. Use Functional Updates
Avoid stale state issues:πΉ 5. Optimize Re-renders
Use:useCallbackuseMemo
πΉ 6. Handle Cleanup Properly
Always clean:- Event listeners
- Timers
- Subscriptions
πΉ 7. Avoid Side Effects Outside Hooks
β Wrong:πΉ 8. Test Custom Hooks
Use libraries like:- React Testing Library
- Jest
- State changes
- Side effects
πΉ 9. Document Your Hooks
Especially for teams:πΉ 10. Think in Composition
π Combine hooks:π§ 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
- Extracting stateful logic without altering component structure
π‘ 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
π‘ 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
Theuse prefix is not stylistic β itβs required for:
-
Linting enforcement (
eslint-plugin-react-hooks) -
Static analysis to ensure:
- Hooks are called correctly
- Rules of hooks are followed
π‘ 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
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:- Logic is trivial
- No reuse exists
- It increases abstraction without clarity
π‘ Why
Over-abstraction:- Makes debugging harder
- Reduces readability
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
π‘ Important nuance
Returning new objects/functions:β Fix
7. How do you prevent stale closures in custom hooks?
β Strong Answer
Stale closures occur when:- Functions capture outdated state
β Fix: Functional updates
π‘ Why
- Uses latest state snapshot
- Avoids dependency issues
8. How should side effects be handled inside custom hooks?
β Strong Answer
Always useuseEffect (or similar)
β Wrong:
π‘ 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
π‘ 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
11. How do you compose multiple custom hooks safely?
β Strong Answer
Hooks can call other hooks:β οΈ 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
- Async updates after unmount
- Uncleaned event listeners
- Timers not cleared
π‘ Why
React doesnβt auto-clean side effects13. How do you make a custom hook configurable and reusable?
β Strong Answer
Use parameters:π‘ 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
π‘ 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
β Fix
π‘ 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:π‘ Use case
- Dynamic behavior
- Multi-tenant apps
- Library design
π Final Thought
At a senior level, custom hooks are not just about:- Reuse
- 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?
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 withuse
C. ESLint uses it to enforce Rules of Hooks
D. It improves performance optimizations
β Correct Answer: C
π‘ Explanation:
Theuse 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 usesuseState
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:
useStatedoesnβt share state - D:
useMemodoesnβt share state
4. What is the risk of returning a new object from a custom hook on every render?
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?
Options:
A. Memory leak B. Stale closure C. Infinite recursion D. Hook violationβ Correct Answer: B
π‘ Explanation:
Function captures outdatedcount β 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?
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?
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. ReplaceuseEffect
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 avoiduseEffect
β 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
π§ 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 delayEdge Cases
- Rapid input changes
- Component unmount during delay
β Solution Explanation
- Store debounced value in state
- Use
setTimeoutinuseEffect - Cleanup previous timer
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
loadingtrue initiallydataupdates after fetch- No memory leaks
Edge Cases
- URL changes quickly
- Network failure
β Solution Explanation
- Use
AbortController - Track loading + error
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
4. π‘ Build useWindowSize
π Problem
Track window width and height.Constraints
- Must cleanup listeners
Expected Behavior
Updates on resizeEdge Cases
- SSR (window undefined)
β Solution
5. π‘ Build useToggle
π Problem
Toggle boolean state with utility functionsExpected Behavior
- Toggle, setTrue, setFalse
Edge Cases
- Multiple toggles quickly
β Solution
6. π Build usePrevious
π Problem
Store previous value of a variableExpected Behavior
Returns previous render valueEdge Cases
- First render β undefined
β Solution
7. π Build useOutsideClick
π Problem
Detect clicks outside a componentConstraints
- Use refs
Edge Cases
- Multiple components using it
β Solution
8. π Build useOnlineStatus
π Problem
Track online/offline stateExpected Behavior
- Updates on network change
Edge Cases
- Browser support
β Solution
9. π΄ Build useThrottle
π Problem
Limit function execution frequencyConstraints
- Should execute immediately then throttle
Edge Cases
- Rapid calls
β Solution
10. π΄ Build useIntersectionObserver
π Problem
Detect if element is visible in viewportConstraints
- Use IntersectionObserver API
Edge Cases
- Browser fallback
β Solution
11. π΄ Build useForm (Reducer-based)
π Problem
Manage complex form stateConstraints
- Handle multiple fields
Edge Cases
- Reset form
β Solution
12. π΄ Build useAsync
π Problem
Handle async function lifecycleExpected Behavior
- loading, error, result
Edge Cases
- Multiple calls overlap
β Solution
13. π΄ Build useEventListener
π Problem
Generic event listener hookConstraints
- Support dynamic target
Edge Cases
- Changing handler
β Solution
14. π΄ Build useClipboard
π Problem
Copy text to clipboardExpected Behavior
Returns copy function + success stateEdge Cases
- Permission denied
β Solution
15. π΄ Build useIdle
π Problem
Detect user inactivityConstraints
- Reset timer on activity
Edge Cases
- Multiple event listeners
β Solution
16. π΄ Build useUndoRedo
π Problem
Implement undo/redo functionalityConstraints
- Maintain history stack
Edge Cases
- Limit history size
β Solution
17. π΄ Build usePagination
π Problem
Handle paginated dataConstraints
- Page navigation
Edge Cases
- Out-of-bound pages
β Solution
18. π΄ Build useHover
π Problem
Detect hover stateEdge Cases
- Mobile devices
β Solution
π Final Insight
These problems test:- Real-world thinking
- Lifecycle awareness
- Cleanup discipline
- Performance considerations
π οΈ Senior React Code Review β Custom Hooks Debugging Challenges
1. β Stale Closure in Counter Hook
π 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 outdatedcount.
β Fix
π§ Best Practice
Always use functional updates when new state depends on previous state.2. β Memory Leak in Fetch Hook
π Whatβs wrong?
State may update after component unmounts.π‘ Why
Fetch is async; component may unmount before it completes.β Fix
π§ Best Practice
Always cancel async operations in effects.3. β Missing Dependency Causing Stale Data
π Whatβs wrong?
Effect does not re-run whenquery changes.
π‘ Why
Empty dependency array freezes the initialquery.
β Fix
π§ Best Practice
Always include all external dependencies.4. β Event Listener Re-Attached Every Render
π Whatβs wrong?
Effect runs on every render β repeated add/remove.π‘ Why
No dependency array β runs after every render.β Fix
π§ Best Practice
Always define effect dependencies explicitly.5. β Infinite Loop in Hook
π Whatβs wrong?
Effect depends ondata, which it updates β infinite loop.
π‘ Why
State update triggers effect again.β Fix
π§ Best Practice
Dependencies should reflect inputs, not outputs.6. β Unstable Function Causing Re-Renders
π Whatβs wrong?
New function instance on every render.π‘ Why
Functions are recreated β breaks memoization.β Fix
π§ Best Practice
Memoize functions when passed to children.7. β Incorrect Ref Usage
π Whatβs wrong?
Ref is never updated.π‘ Why
useRef doesnβt auto-update like state.
β Fix
π§ Best Practice
Update refs inside effects.8. β Breaking Hook Rules
π Whatβs wrong?
Hook is conditionally called.π‘ Why
Breaks hook order β undefined behavior.β Fix
π§ Best Practice
Never call hooks conditionally.9. β Race Condition in Fetch
π Whatβs wrong?
Older request may overwrite newer one.π‘ Why
Async responses return out of order.β Fix
π§ Best Practice
Handle race conditions in async hooks.10. β Derived State Stored Incorrectly
π Whatβs wrong?
Derived state stored unnecessarily.π‘ Why
Adds extra render cycle.β Fix
π§ Best Practice
Avoid storing derived state.11. β Missing Cleanup for Timer
π Whatβs wrong?
Interval never cleared.π‘ Why
Leads to memory leaks.β Fix
π§ Best Practice
Always cleanup timers.12. β Using State Instead of Ref for Mutable Value
π Whatβs wrong?
State update inside render β infinite loop.π‘ Why
State updates trigger re-render immediately.β Fix
π§ Best Practice
UseuseRef for non-render-triggering values.
13. β Over-Fetching Due to Object Dependency
π Whatβs wrong?
filter is an object β new reference each render.
π‘ Why
Triggers unnecessary effect runs.β Fix
π§ Best Practice
Stabilize object dependencies.14. β Hook Not SSR Safe
π Whatβs wrong?
Breaks in SSR (window undefined).π‘ Why
Server doesnβt havewindow.
β Fix
π§ Best Practice
Guard browser APIs in hooks.15. β Incorrect Dependency on Function
π Whatβs wrong?
Effect runs every render iffn is unstable.
π‘ Why
Functions are recreated unless memoized.β Fix
- Either memoize
fnin parent OR - Remove from deps if safe
π§ Best Practice
Stabilize callbacks usinguseCallback.
16. β State Reset on Key Change
π Whatβs wrong?
State does not reset whenkey changes.
π‘ Why
useState only initializes once.
β Fix
π§ Best Practice
Handle prop-driven resets explicitly.17. β Multiple Event Listeners Leak
π Whatβs wrong?
Anonymous function cannot be removed.π‘ Why
Cleanup needs same reference.β Fix
π§ Best Practice
Always store handler references.π Final Takeaway
These bugs reflect real production failures:- Stale closures
- Race conditions
- Memory leaks
- Dependency mistakes
π§ 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
- Create debounce hook
- Maintain cache with
useRef - Fetch only if query not cached
- 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
- Use
useReducerfor form state - Store schema separately
- Generate fields dynamically
- 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
- Track scroll position
- Trigger fetch near bottom
- Use refs for container height
- 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()+ ContextuseProtectedRoute()
πͺ Approach
- Store token in localStorage
- Sync with context
- Handle login/logout actions
- 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
- Initialize socket in hook
- Listen for messages
- Update state safely
- 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
- Maintain history array
- Track pointer index
- Slice history on new action
- 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
- Use Map for cache
- Track in-flight requests
- Return cached data immediately
- 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
- Track dragged item with ref
- Handle drag events
- Update state on drop
- 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
- Store flags globally
- Fetch from API
- Provide via context
- 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
- Observe element visibility
- Trigger load when visible
- Unobserve after load
- Cache loaded state
π Final Insight
These problems simulate:- Real product features
- Performance-critical systems
- Scalable architecture design
- 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:- Check returned values (new objects/functions)
- Inspect dependencies
- Use React DevTools profiler
- 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:
β 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:
β 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