π React useReducer β Complete In-Depth Guide
1. Introduction
πΉ What is useReducer
useReducer is a React Hook used for managing complex state logic in a component. It is an alternative to useState, especially useful when:
- State has multiple sub-values
- State transitions depend on previous state
- Logic is complex or reusable
πΉ Why it is important in React
- Centralizes state logic in one place
- Makes state transitions predictable
- Improves readability for complex components
- Encourages pure functions and better testability
- Scales better than
useStatefor non-trivial logic
πΉ When and why we use it
UseuseReducer when:
β Good use cases:
- Complex state transitions
- Multiple related state variables
- Deeply nested updates
- Business logic-heavy components
- Form management (with multiple fields)
- State depends heavily on previous state
β Avoid when:
- State is simple (use
useState) - No complex transitions or logic
2. Concepts / Internal Workings
πΉ Core Concepts
1. Reducer Function
A pure function that determines how state changes.- Receives current state
- Receives an action
- Returns new state (immutable update)
2. Action
An object describing what happened3. Dispatch
A function used to trigger state changes4. State
The current value managed by the reducerπΉ How it works internally in React
-
Component calls
useReducer(reducer, initialState) -
React:
- Stores state internally
- Returns
[state, dispatch]
-
When
dispatch(action)is called:- React calls reducer with
(currentState, action) - Gets new state
- Triggers re-render
- React calls reducer with
βοΈ Key Internal Behavior
- React uses reference comparison (
Object.is) to detect changes - If reducer returns same object β no re-render
- If new object β re-render occurs
πΉ Relationship with other React features
πΈ useState
useStateis a simplified version ofuseReducer- Internally, React implements
useStateusing a reducer-like pattern
πΈ useContext
-
Common pairing:
useReducerβ manages stateuseContextβ shares state globally
πΈ React Rendering
- Dispatch triggers a reconciliation cycle
- React schedules updates efficiently (especially in concurrent mode)
πΈ Redux
useReduceris a local Redux-like pattern- No middleware, but same core idea
3. Syntax & Examples
πΉ Basic Syntax
πΉ Example 1: Counter
πΉ Example 2: Complex State Object
πΉ Example 3: Todo List
πΉ Example 4: Lazy Initialization
πΉ Example 5: useReducer + useContext
πΉ Mini Variations
Dispatch with payload
Multiple reducers (manual composition)
4. Edge Cases / Common Mistakes
π΄ 1. Mutating state directly
β Wrong:π΄ 2. Returning same reference
π΄ 3. Missing default case
π΄ 4. Dispatch inside render
π΄ 5. Overusing useReducer
π Not every state needs reducer logic π Adds unnecessary complexityπ΄ 6. Deep nested updates
π΄ 7. Async logic inside reducer
β Avoid:π΄ 8. Dispatch identity misunderstanding
dispatchis stable across renders- Safe to pass down without memoization
5. Best Practices
β 1. Keep reducer pure
- No side effects
- No API calls
- No randomness
β 2. Use action constants
β 3. Group related logic
- One reducer per domain (user, cart, form)
- Avoid giant reducers
β 4. Use meaningful action names
β"SET"
β
"SET_USER_NAME"
β 5. Normalize complex state
Instead of deep nesting:β
6. Combine with useContext for global state
- Lightweight alternative to Redux
- Good for medium-sized apps
β 7. Optimize re-renders
- Avoid unnecessary object creation
- Split reducers if needed
β 8. Lazy initialization for heavy state
β 9. Debugging strategy
- Log actions inside reducer:
- Track state transitions
β 10. Testing reducers
- Reducers are pure β easy to test
π§ Final Mental Model
Think ofuseReducer as:
βA state machine where actions describe events, and reducer defines how state evolves.β
π§ Advanced useReducer β Senior-Level Conceptual Questions & Answers
1. How is useReducer fundamentally different from useState under the hood?
β Answer
At a high level, both are similar β React internally modelsuseState as a specialized reducer.
π Key Differences
| Aspect | useState | useReducer |
|---|---|---|
| API | Simple setter | Dispatch + reducer |
| Logic location | Inline | Centralized |
| State transitions | Implicit | Explicit |
βοΈ Internal Insight
React internally does something like:π§ WHY it matters
useReducergives predictable state transitions- Better for debugging (action logs)
- More scalable for complex logic
2. Why must a reducer be a pure function, and what breaks if itβs not?
β Answer
Reducers must be pure because React relies on:- Deterministic state updates
- Safe re-execution (especially in concurrent rendering)
β Problem with impure reducers
π₯ What breaks?
- React may call reducer multiple times
- Causes duplicate API calls
- Leads to inconsistent UI
π§ WHY
React may replay updates during rendering (Concurrent Mode)3. How does React determine whether to re-render after dispatch?
β Answer
React uses reference equality (Object.is).
π΄ Subtle Bug
π§ WHY
React assumes:- Same reference = no change
- New reference = update required
4. What are the trade-offs between useReducer and Redux?
β Answer
π Comparison
| Feature | useReducer | Redux |
|---|---|---|
| Scope | Local | Global |
| Middleware | β | β |
| DevTools | β | β |
| Boilerplate | Low | High |
π§ When to choose
useReducerβ component-level or medium complexity- Redux β large apps, cross-cutting concerns
π§ WHY
Redux adds:- Middleware pipeline
- Time-travel debugging
- Predictable global architecture
5. Why is dispatch stable across renders, and why does that matter?
β Answer
React guarantees thatdispatch is referentially stable.
π§ WHY
- Avoid unnecessary re-renders in children
- Safe to pass down without
useCallback
π₯ Contrast
6. What happens if multiple dispatches occur synchronously?
β Answer
React batches updates.Result:
- Reducer runs twice
- Final state reflects both updates
π§ WHY
React queues updates and processes them in order7. How does lazy initialization in useReducer improve performance?
β Answer
π§ WHY
initruns only once- Avoids recomputation on every render
π₯ Use case
8. How would you structure reducers in a large-scale application?
β Answer
πΉ Pattern: Reducer Composition
π§ WHY
- Separation of concerns
- Maintainability
- Scalable architecture
9. Why is putting async logic inside reducers an anti-pattern?
β Answer
Reducers must be pure and synchronous.β Bad
β Correct
π§ WHY
- Async logic breaks predictability
- Hard to test
- Violates functional programming principles
10. How does useReducer behave in concurrent rendering?
β Answer
React may:- Pause
- Resume
- Replay reducer calls
π§ WHY
Concurrent rendering allows:- Interruptible updates
- Better UX
β οΈ Implication
Reducers must be:- Pure
- Idempotent
11. What are the pitfalls of deeply nested state in reducers?
β Answer
π΄ Problems
- Verbose
- Error-prone
- Hard to maintain
β Solution
- Normalize state
- Split reducers
12. When does useReducer become an anti-pattern?
β Answer
β Overuse scenarios
- Simple boolean toggles
- Independent state variables
π§ WHY
- Adds unnecessary abstraction
- Reduces readability
13. How do you debug complex reducer logic?
β Answer
πΉ Techniques
- Log actions
- Trace state transitions
- Use custom middleware-like wrappers
π§ WHY
Reducers are deterministic β easy to trace14. How does useReducer interact with useContext in global state design?
β Answer
πΉ Pattern
π§ WHY
- Avoid prop drilling
- Share state globally
β οΈ Trade-off
- All consumers re-render unless optimized
15. How can you prevent unnecessary re-renders when using useReducer + Context?
β Answer
πΉ Techniques
- Split contexts
- Memoize selectors
- Use libraries like Zustand/Recoil if needed
π§ WHY
Context updates trigger all consumers16. Why are action objects preferred over direct function calls?
β Answer
π§ WHY
- Declarative
- Serializable
- Easier debugging
- Enables logging/history
17. What happens if the reducer throws an error?
β Answer
- Component crashes
- Error propagates to nearest error boundary
π§ WHY
Reducers run during render phaseβ Solution
- Validate inputs
- Use error boundaries
18. How would you model a finite state machine using useReducer?
β Answer
π§ WHY
- Explicit transitions
- Prevent invalid states
π Final Thought
At a senior level,useReducer is not just a hook β itβs:
A predictable state transition system that helps you model complex UI logic with clarity and control.
π§ Advanced useReducer β Senior-Level MCQs
1. When will a component NOT re-render after a dispatch?
Question:
dispatch({ type: "increment" })?
Options:
A. Component re-renders with updated count B. Component does not re-render C. React throws an error D. Behavior is undefinedβ Correct Answer: B
π‘ Explanation:
React compares state using reference equality (Object.is).
Since the same object reference is returned, React skips re-render.
β Why others are wrong:
- A: Incorrect β mutation doesnβt trigger re-render
- C: No runtime error
- D: Behavior is deterministic
2. What happens if reducer returns a completely new object but with identical values?
Options:
A. No re-render B. Re-render occurs C. React shallow compares properties D. React throws warningβ Correct Answer: B
π‘ Explanation:
React only checks reference, not deep equality. New object β re-render.β Others:
- A: Wrong β reference changed
- C: React does NOT deep/shallow compare
- D: No warning
3. What is the biggest risk of putting side effects inside a reducer?
Options:
A. Performance degradation B. Duplicate or inconsistent side effects C. Memory leaks D. Reducer stops workingβ Correct Answer: B
π‘ Explanation:
React may re-run reducers (especially in concurrent mode), causing duplicate API calls or inconsistent behavior.β Others:
- A: Secondary issue
- C: Not primary concern
- D: Reducer still works
4. What guarantees that dispatch does not change between renders?
Options:
A. React memoizes it withuseCallback
B. It is bound once during hook initialization
C. It is recreated every render but optimized
D. JavaScript closures
β Correct Answer: B
π‘ Explanation:
React internally ensuresdispatch is stable, created once per hook.
β Others:
- A: Not user-level memoization
- C: Not recreated
- D: Partial but not the full reason
5. What happens with multiple synchronous dispatches?
Options:
A. Only last dispatch applies B. Both dispatches apply sequentially C. Only first applies D. Behavior depends on batchingβ Correct Answer: B
π‘ Explanation:
React queues updates β reducer runs twice β both applied.β Others:
- A/C: Incorrect
- D: Batching doesnβt skip updates
6. What is the purpose of the third argument in useReducer?
Options:
A. Middleware B. Lazy initialization C. Debugging D. Async dispatch handlingβ Correct Answer: B
π‘ Explanation:
initFn computes initial state once.
β Others:
- A: Not supported
- C/D: Not related
7. What happens if reducer throws an error?
Options:
A. Ignored silently B. Component crashes C. State resets D. React retries reducerβ Correct Answer: B
π‘ Explanation:
Reducers run during render β error propagates β nearest error boundary.β Others:
- A: No silent fail
- C: No reset
- D: No retry
8. Which scenario justifies using useReducer over useState?
Options:
A. Managing a single boolean B. Handling multiple independent states C. Complex state transitions dependent on previous state D. Static valuesβ Correct Answer: C
π‘ Explanation:
Reducer shines when transitions are complex and interdependent.β Others:
- A/B/D: Better suited for
useState
9. What is a key downside of combining useReducer with useContext?
Options:
A. Dispatch becomes unstable B. All consumers re-render on state change C. Reducer cannot handle nested state D. Actions become asyncβ Correct Answer: B
π‘ Explanation:
Context triggers re-render for all consumers.β Others:
- A: Dispatch is stable
- C: Reducer can handle nested state
- D: Actions remain sync
10. What is the effect of missing a default case in reducer?
Options:
A. React throws error B. State becomes undefined C. No effect D. Reducer stops executingβ Correct Answer: B
π‘ Explanation:
If no case matches and no default β returnsundefined β breaks state.
β Others:
- A/D: Not automatic
- C: Incorrect
11. Why are action objects preferred over direct function calls?
Options:
A. Faster execution B. Easier serialization and debugging C. Required by React D. Enables async behaviorβ Correct Answer: B
π‘ Explanation:
Action objects:- Loggable
- Serializable
- Traceable
β Others:
- A: No speed benefit
- C: Not required
- D: Not inherent
12. What is the biggest issue with deeply nested state updates?
Options:
A. Performance B. Verbosity and maintainability C. React incompatibility D. Dispatch failureβ Correct Answer: B
π‘ Explanation:
Deep updates become:- Hard to read
- Error-prone
β Others:
- A: Minor
- C/D: Not true
13. Why is this pattern problematic?
Options:
A. Random values not allowed B. Breaks purity expectations C. Causes memory leaks D. No issueβ Correct Answer: B
π‘ Explanation:
Reducers should be deterministic; randomness breaks predictability.β Others:
- A: Not restricted
- C: No leak
- D: Incorrect
14. What happens if reducer returns undefined?
Options:
A. React ignores update B. Component crashes C. State becomes undefined D. React retries reducerβ Correct Answer: C
π‘ Explanation:
State becomesundefined, likely causing runtime issues.
β Others:
- A: Not ignored
- B: Not immediate crash
- D: No retry
15. How does useReducer help in modeling state machines?
Options:
A. By storing multiple states B. By enforcing valid transitions C. By preventing re-renders D. By batching updatesβ Correct Answer: B
π‘ Explanation:
Reducer defines allowed transitions β avoids invalid states.β Others:
- A: Not unique
- C/D: Unrelated
16. What is the consequence of dispatching inside render?
Options:
A. One extra render B. Infinite re-render loop C. No effect D. React warning onlyβ Correct Answer: B
π‘ Explanation:
Dispatch β state update β render β dispatch again β infinite loop.β Others:
- A: Not limited
- C: Incorrect
- D: It crashes, not just warns
17. Why is splitting reducers beneficial?
Options:
A. Improves React performance automatically B. Improves maintainability and separation C. Reduces memory usage D. Enables async reducersβ Correct Answer: B
π‘ Explanation:
Separation of concerns β easier scaling and debugging.β Others:
- A: Not automatic
- C: Minimal impact
- D: Not related
18. What is a subtle performance issue with large reducers?
Options:
A. React skips updates B. Reducer runs on every dispatch C. Dispatch becomes async D. State becomes staleβ Correct Answer: B
π‘ Explanation:
Every dispatch executes reducer β large logic can slow updates.β Others:
- A: Not true
- C: Dispatch is sync
- D: Not inherent
π Final Insight
At a senior level, these questions test whether you understand:- State identity vs value
- Purity and concurrency implications
- Architectural trade-offs
- Real-world scaling issues
π§ Advanced useReducer Coding Problems (Senior-Level)
1. Shopping Cart with Derived Totals
π§© Problem
Build a shopping cart where:- Users can add/remove/update items
- Each item has
price,quantity - Show total items and total price
βοΈ Constraints
- Avoid recalculating totals outside reducer
- Handle duplicate items (merge quantities)
β Expected Behavior
β οΈ Edge Cases
- Removing non-existent item
- Quantity = 0 β remove item
π§ Solution Approach
Step 1: State Shape
Step 2: Reducer Logic
Step 3: Why reducer?
- Derived state consistency
- Avoid scattered logic
2. Multi-Step Form Wizard
π§© Problem
Create a form with multiple steps:- Step navigation (next/back)
- Store form data across steps
- Reset functionality
βοΈ Constraints
- Cannot lose previous step data
- Validation per step
β Expected Behavior
- Step 1 β Step 2 β Back β data persists
β οΈ Edge Cases
- Jumping steps
- Invalid inputs
π§ Solution
State
Reducer
Insight
Reducer ensures state + navigation consistency3. Undo/Redo System
π§© Problem
Implement undo/redo functionality for text editing.βοΈ Constraints
- Maintain history
- Limit history size (e.g., 10)
β Expected
β οΈ Edge Cases
- Undo beyond history
- Redo after new action β clear redo stack
π§ Solution
State
Reducer
WHY
Reducer models state timeline4. API Request State Manager
π§© Problem
Handle API states:- loading
- success
- error
βοΈ Constraints
- Avoid inconsistent states
β Expected
β οΈ Edge Cases
- Multiple requests
- Stale responses
π§ Solution
5. Dynamic Form Builder
π§© Problem
Form fields are dynamic (add/remove fields at runtime)βοΈ Constraints
- Fields stored as array
- Each field has validation
β οΈ Edge Cases
- Duplicate field IDs
- Removing active field
π§ Solution
Reducer manages:6. Notification Queue System
π§© Problem
Manage toast notifications:- Add/remove notifications
- Auto-dismiss
βοΈ Constraints
- FIFO order
β οΈ Edge Cases
- Duplicate messages
- Rapid dispatch
π§ Solution
7. File Upload Manager
π§© Problem
Track multiple file uploads with progressβοΈ Constraints
- Each file has progress %
- Handle cancel
β οΈ Edge Cases
- Cancel mid-upload
- Retry
π§ Solution
8. Role-Based Access Control
π§© Problem
Manage user roles and permissions dynamicallyβοΈ Constraints
- Roles can change at runtime
β οΈ Edge Cases
- Conflicting permissions
π§ Solution
Reducer enforces:9. Drag-and-Drop List Reordering
π§© Problem
Reorder items in a listβοΈ Constraints
- Maintain immutability
β οΈ Edge Cases
- Same index move
- Invalid indices
π§ Solution
10. Theme Manager (Global State)
π§© Problem
Toggle and persist themeβοΈ Constraints
- Sync with localStorage
β οΈ Edge Cases
- Initial load mismatch
π§ Solution
Reducer +useEffect
11. Pagination State Manager
π§© Problem
Handle page navigation + page sizeβοΈ Constraints
- Reset page on size change
β οΈ Edge Cases
- Out-of-range pages
π§ Solution
12. Form Validation Engine
π§© Problem
Validate multiple fields with rulesβοΈ Constraints
- Real-time validation
β οΈ Edge Cases
- Async validation
π§ Solution
Reducer stores:13. Shopping Wishlist with Sync
π§© Problem
Sync wishlist with backendβοΈ Constraints
- Optimistic updates
β οΈ Edge Cases
- API failure rollback
π§ Solution
14. Tab Manager
π§© Problem
Manage dynamic tabsβοΈ Constraints
- Only one active tab
β οΈ Edge Cases
- Closing active tab
π§ Solution
15. Keyboard Shortcut Manager
π§© Problem
Map keyboard shortcuts to actionsβοΈ Constraints
- Prevent conflicts
β οΈ Edge Cases
- Duplicate bindings
π§ Solution
Reducer manages:16. Collaborative Cursor Tracker
π§© Problem
Track multiple user cursors (like Figma)βοΈ Constraints
- Real-time updates
β οΈ Edge Cases
- Disconnect cleanup
π§ Solution
17. Filter + Sort Engine
π§© Problem
Apply filters and sorting to datasetβοΈ Constraints
- Combine multiple filters
β οΈ Edge Cases
- Empty results
π§ Solution
Reducer manages:18. Chat Message Buffer
π§© Problem
Handle incoming messages + scroll behaviorβοΈ Constraints
- Limit buffer size
β οΈ Edge Cases
- Duplicate messages
π§ Solution
19. Game State Manager (Finite State Machine)
π§© Problem
Game states:- idle β playing β paused β game over
βοΈ Constraints
- Invalid transitions not allowed
β οΈ Edge Cases
- Pause from idle
π§ Solution
Reducer enforces transitionsπ Final Thought
These problems test:- State modeling
- Reducer design
- Edge-case thinking
- Real-world architecture
π§ Advanced useReducer Debugging Challenges (Senior-Level)
1. Silent State Mutation Bug
π Buggy Code
β Whatβs Wrong
State is being mutated directly.π€ WHY it happens
React relies on reference equality (Object.is). Returning the same object prevents re-render.
β Fix
π§ Best Practice
Always treat state as immutable.2. Missing Default Case Crash
π Buggy Code
β Whatβs Wrong
No return for unknown actions β returnsundefined.
π€ WHY
React expects reducer to always return valid state.β Fix
π§ Best Practice
Always include a default fallback.3. Infinite Re-render Loop
π Buggy Code
β Whatβs Wrong
Dispatch inside render.π€ WHY
Dispatch β state update β render β dispatch again β infinite loop.β Fix
π§ Best Practice
Never trigger state updates during render.4. Async Logic Inside Reducer
π Buggy Code
β Whatβs Wrong
Side effects inside reducer.π€ WHY
Reducers must be pure; React may re-run them.β Fix
π§ Best Practice
Keep reducers pure and synchronous.5. Stale State Assumption
π Buggy Code
β Whatβs Wrong
Expecting updated state immediately.π€ WHY
State updates are scheduled, not immediate.β Fix
UseuseEffect:
π§ Best Practice
Treat state updates as async from UI perspective.6. Recreating Initial State Expensively
π Buggy Code
β Whatβs Wrong
expensiveInit() runs on every render.
π€ WHY
Initializer is executed immediately.β Fix
π§ Best Practice
Use lazy initialization.7. Deeply Nested State Update Bug
π Buggy Code
β Whatβs Wrong
Overwrites entireuser.profile structure.
π€ WHY
Missing spread for nested objects.β Fix
π§ Best Practice
Always preserve nested structure.8. Dispatching Wrong Action Shape
π Buggy Code
β Whatβs Wrong
Reducer expects object, not string.π€ WHY
Mismatch in action contract.β Fix
π§ Best Practice
Standardize action shape.9. Unnecessary Re-renders with Context
π Buggy Code
β Whatβs Wrong
New object every render β re-renders all consumers.π€ WHY
Reference changes trigger context updates.β Fix
π§ Best Practice
Memoize provider values.10. Reducer Too Large (Performance Issue)
π Buggy Code
β Whatβs Wrong
Heavy computation on every dispatch.π€ WHY
Reducer runs for every action.β Fix
Split reducers:π§ Best Practice
Keep reducers small and focused.11. Returning New Object Unnecessarily
π Buggy Code
β Whatβs Wrong
Triggers unnecessary re-render.π€ WHY
New reference even if no change.β Fix
π§ Best Practice
Return same reference if unchanged.12. Using Random Values in Reducer
π Buggy Code
β Whatβs Wrong
Non-deterministic reducer.π€ WHY
Breaks predictability.β Fix
Generate outside reducer.π§ Best Practice
Reducers must be deterministic.13. Forgetting to Handle Edge Action
π Buggy Code
β Whatβs Wrong
Fails ifaction.id undefined.
π€ WHY
No validation.β Fix
π§ Best Practice
Validate action payloads.14. Using Reducer for Simple State
π Buggy Code
β Whatβs Wrong
Over-engineered.π€ WHY
No complex logic.β Fix
UseuseState.
π§ Best Practice
Choose the right abstraction.15. State Reset Bug
π Buggy Code
β Whatβs Wrong
initialState might be stale or mutated.
π€ WHY
Shared reference issues.β Fix
π§ Best Practice
Avoid shared mutable references.16. Dispatch Inside Loop
π Buggy Code
β Whatβs Wrong
Multiple re-renders.π€ WHY
Each dispatch triggers update.β Fix
Batch updates or single action.π§ Best Practice
Minimize dispatch frequency.17. Ignoring Action Payload Shape
π Buggy Code
β Whatβs Wrong
Assumes payload shape blindly.π€ WHY
Runtime crashes if payload invalid.β Fix
Validate payload.π§ Best Practice
Use type-safe patterns.π Final Thought
These bugs reflect real production issues:- Identity vs mutation
- Concurrency assumptions
- Performance pitfalls
- Architectural misuse
π§ Real-World Machine Coding Problems using useReducer (Senior-Level)
1. Advanced E-commerce Cart System
π§© Requirements
- Add/remove/update items
- Support discounts, coupons, taxes
- Multi-currency support
- Persist cart (localStorage)
π₯οΈ UI Behavior
- Live updates on quantity change
- Coupon apply/remove UI
- Price breakdown (subtotal, tax, total)
π State Flow
- Actions:
ADD_ITEM,REMOVE_ITEM,APPLY_COUPON,SET_CURRENCY - Derived values computed inside reducer
β οΈ Edge Cases
- Invalid coupon
- Currency switch recalculation
- Negative totals
β‘ Performance
- Avoid recalculating totals on every render
- Memoize currency conversions
ποΈ Architecture
- Single reducer with normalized state
- Optional split: pricingReducer, cartReducer
π§ Approach
- Define normalized state (
itemsById) - Handle item merge logic
- Compute totals inside reducer
- Sync with storage via
useEffect
2. Collaborative Kanban Board (Trello-like)
π§© Requirements
- Drag/drop cards across columns
- Real-time updates (simulate via actions)
- Add/edit/delete cards
π₯οΈ UI Behavior
- Smooth drag animations
- Column-wise grouping
π State Flow
β οΈ Edge Cases
- Dropping in same position
- Missing card references
β‘ Performance
- Avoid re-rendering entire board
- Use memoized selectors
ποΈ Architecture
- Split reducers: boardReducer, cardReducer
π§ Approach
- Normalize data
- Handle MOVE_CARD action carefully
- Ensure immutability for lists
3. Real-Time Chat Application
π§© Requirements
- Send/receive messages
- Typing indicators
- Message status (sent/read)
π₯οΈ UI Behavior
- Scroll to latest message
- Show typing users
π State Flow
β οΈ Edge Cases
- Duplicate messages
- Out-of-order delivery
β‘ Performance
- Limit message buffer
- Virtualize message list
ποΈ Architecture
- messageReducer + uiReducer
π§ Approach
- Deduplicate messages
- Maintain message IDs
- Handle status updates
4. Form Builder (Dynamic + Conditional Logic)
π§© Requirements
- Add/remove fields dynamically
- Conditional visibility (if X β show Y)
- Validation rules
π₯οΈ UI Behavior
- Fields appear/disappear dynamically
π State Flow
- fields config + values + errors
β οΈ Edge Cases
- Circular dependencies
- Hidden field validation
β‘ Performance
- Avoid recalculating all conditions
ποΈ Architecture
- Separate config vs runtime state
π§ Approach
- Store field schema
- Evaluate conditions in reducer
- Trigger validations on change
5. Infinite Scroll Feed (Social Media)
π§© Requirements
- Fetch paginated data
- Merge results
- Handle loading/error
π₯οΈ UI Behavior
- Scroll triggers fetch
- Loader at bottom
π State Flow
β οΈ Edge Cases
- Duplicate pages
- Rapid scroll triggering
β‘ Performance
- Debounce fetch
- Prevent duplicate requests
ποΈ Architecture
- fetchReducer (FSM-like)
π§ Approach
- Track page state
- Append new data
- Prevent parallel fetches
6. Multi-Tab Session Manager
π§© Requirements
- Manage multiple tabs (like browser tabs)
- Persist tab state
- Restore sessions
π₯οΈ UI Behavior
- Switch tabs instantly
- Close/open tabs
π State Flow
β οΈ Edge Cases
- Closing active tab
- Duplicate tab IDs
β‘ Performance
- Avoid re-rendering inactive tabs
ποΈ Architecture
- tabReducer + contentReducer
π§ Approach
- Maintain tab registry
- Handle active switching
- Persist in storage
7. Advanced Filter Engine (E-commerce/Search)
π§© Requirements
- Multi-select filters
- Range filters
- Sort options
π₯οΈ UI Behavior
- Real-time filtering
π State Flow
β οΈ Edge Cases
- Conflicting filters
- Empty results
β‘ Performance
- Memoize filtering logic
ποΈ Architecture
- filterReducer + dataReducer
π§ Approach
- Store raw data separately
- Apply filters in reducer or selector
- Optimize with memoization
8. Notification Center with Priorities
π§© Requirements
- Queue notifications
- Priority-based ordering
- Auto-dismiss
β οΈ Edge Cases
- Duplicate notifications
- Expired notifications
β‘ Performance
- Limit queue size
π§ Approach
- Priority queue logic in reducer
9. File Upload Dashboard
π§© Requirements
- Upload multiple files
- Track progress
- Retry/cancel
π State Flow
β οΈ Edge Cases
- Network failure
- Partial uploads
β‘ Performance
- Avoid updating entire list
π§ Approach
- Update specific file entry
10. Undo/Redo Rich Text Editor
π§© Requirements
- Full history tracking
- Keyboard shortcuts
β οΈ Edge Cases
- Large history memory
β‘ Performance
- Limit history size
π§ Approach
- past/present/future structure
11. Permissions Management Dashboard
π§© Requirements
- Assign roles
- Toggle permissions
β οΈ Edge Cases
- Conflicting rules
π§ Approach
- Normalize roles + permissions
12. Scheduling Calendar (Google Calendar-like)
π§© Requirements
- Add/edit events
- Handle overlaps
β οΈ Edge Cases
- Time conflicts
β‘ Performance
- Efficient time lookup
π§ Approach
- Store events indexed by date
13. Shopping Checkout Flow (Multi-step + Validation)
π§© Requirements
- Steps: Address β Payment β Review
- Validation per step
β οΈ Edge Cases
- Partial completion
π§ Approach
- FSM-like reducer
14. Data Grid with Inline Editing
π§© Requirements
- Edit rows inline
- Bulk updates
β οΈ Edge Cases
- Validation errors
β‘ Performance
- Row-level updates
π§ Approach
- Normalize rows by ID
15. Real-Time Stock Dashboard
π§© Requirements
- Live price updates
- Highlight changes
β οΈ Edge Cases
- Rapid updates
β‘ Performance
- Throttle updates
π§ Approach
- Update only changed stocks
16. Feature Flag System
π§© Requirements
- Enable/disable features dynamically
β οΈ Edge Cases
- Dependency between flags
π§ Approach
- Reducer enforces rules
π Final Insight
These problems test architectural thinking, not just coding:- State normalization
- Reducer composition
- Performance optimization
- Edge-case handling
- Real-world constraints
π§ Senior-Level Interview Questions β useReducer
1. When would you choose useReducer over useState in a real production system?
π Follow-up
- What signals tell you state is βcomplex enoughβ?
- Can you refactor from
useStatetouseReducersafely?
β Strong Answer
UseuseReducer when:
- State transitions are interdependent
- Multiple state variables must change atomically
- Logic is reused or needs testability
β Weak Answer
βWhen state is complex.βπ Fails because it doesnβt define what complexity means or give criteria.
2. How does React decide whether to re-render after a reducer update?
π Follow-up
- What happens if you mutate state?
- Does React do deep comparison?
β Strong Answer
React uses reference equality (Object.is).
If reducer returns the same reference β no re-render.
β Weak Answer
βReact checks if values changed.βπ Incorrect β React does NOT deep compare.
3. Explain why reducers must be pure, especially in React 18+.
π Follow-up
- What breaks in concurrent rendering?
- Give a real bug example
β Strong Answer
Reducers may be re-run or replayed in concurrent rendering. Impure reducers cause:- Duplicate API calls
- Inconsistent state
β Weak Answer
βBecause Redux says so.βπ No understanding of Reactβs execution model.
4. Design a global state system using useReducer and useContext. What are the trade-offs?
π Follow-up
- How do you prevent unnecessary re-renders?
- When would you switch to Redux/Zustand?
β Strong Answer
- Use reducer for logic, context for distribution
- Split contexts or memoize value
- Simpler than Redux
- But causes full tree re-renders
β Weak Answer
βIt replaces Redux.βπ Oversimplification β ignores scaling issues.
5. How would you debug a reducer that behaves inconsistently in production but not locally?
π Follow-up
- What tools/strategies?
- What assumptions would you question?
β Strong Answer
- Log actions + state transitions
- Check for impure logic
- Validate concurrency assumptions
β Weak Answer
βAdd console logs.βπ Too shallow β no strategy.
6. What are the performance implications of large reducers?
π Follow-up
- How would you optimize?
- When to split reducers?
β Strong Answer
Reducers run on every dispatch β large logic slows updates. Optimize via:- Splitting reducers
- Memoized selectors
β Weak Answer
βReducers are fast.βπ Ignores scale.
7. How would you model a finite state machine using useReducer?
π Follow-up
- How do you prevent invalid transitions?
β Strong Answer
Use state + allowed transitions:β Weak Answer
βUse switch case.βπ Misses FSM concept.
8. What is a subtle bug caused by returning a new object unnecessarily?
π Follow-up
- How does this impact performance?
β Strong Answer
Triggers unnecessary re-renders:β Weak Answer
βNo issue.βπ Misses rendering implications.
9. How would you handle async flows with useReducer?
π Follow-up
- Why not inside reducer?
- Compare with Redux middleware
β Strong Answer
UseuseEffect to dispatch lifecycle actions:
β Weak Answer
βPut fetch in reducer.βπ Violates purity.
10. How do you avoid unnecessary re-renders when using useReducer with Context?
π Follow-up
- What patterns help?
β Strong Answer
- Split contexts
- Memoize provider value
- Use selector-based consumption
β Weak Answer
βUse memo.βπ Too vague.
11. What are the trade-offs of normalizing state in reducers?
π Follow-up
- When is normalization overkill?
β Strong Answer
Pros:- Easier updates
- Avoid deep nesting
- More complex structure
β Weak Answer
βAlways normalize.βπ Not always necessary.
12. Explain a real-world scenario where useReducer improves debugging.
π Follow-up
- How would you log actions?
β Strong Answer
Action-based updates β easier tracing:β Weak Answer
βItβs easier.βπ No concrete reasoning.
13. How does batching affect multiple dispatch calls?
π Follow-up
- Does React skip any updates?
β Strong Answer
React batches but processes all actions sequentially.β Weak Answer
βOnly last dispatch runs.βπ Incorrect.
14. Whatβs the risk of deeply nested state in reducers?
π Follow-up
- How would you refactor?
β Strong Answer
- Verbose updates
- Error-prone
- Normalize state
- Split reducers
β Weak Answer
βItβs fine.βπ Ignores maintainability.
15. How would you design undo/redo using useReducer?
π Follow-up
- What data structure?
β Strong Answer
Use:β Weak Answer
βStore previous state.βπ Too vague.
16. When does useReducer become an anti-pattern?
π Follow-up
- Give real examples
β Strong Answer
- Simple toggles
- Independent state
β Weak Answer
βNever.βπ Shows poor judgment.
17. How does dispatch stability influence component design?
π Follow-up
- Do you need
useCallback?
β Strong Answer
Dispatch is stable β safe to pass down.β Weak Answer
βWrap in useCallback.βπ Unnecessary optimization.
18. What is a common production bug related to stale closures with useReducer?
π Follow-up
- How to fix?
β Strong Answer
Using outdated state outside reducer logic. Fix with:- Proper dependencies
- Moving logic into reducer
β Weak Answer
βNot sure.βπ Misses real-world issue.
19. How would you scale useReducer in a large application?
π Follow-up
- When to move to external state library?
β Strong Answer
- Split reducers
- Use context layering
-
Move to Redux/Zustand when:
- Cross-cutting state grows
β Weak Answer
βJust use one reducer.βπ Not scalable.
20. What mental model do you use when designing reducers?
π Follow-up
- How do you ensure correctness?
β Strong Answer
Think of reducer as:State machine with explicit transitionsEnsures predictability and testability.
β Weak Answer
βJust switch case logic.βπ Lacks abstraction.
π Final Insight
A strong candidate demonstrates:- State modeling skills
- Understanding of React internals
- Trade-off awareness
- Debugging mindset
When, why, and how it behaves under real-world constraints.