React Hooks & Component Patterns
- Core hooks —
useState,useEffect,useContext,useRef - Performance hooks —
useMemo,useCallback,useTransition - Custom hooks — extracting reusable logic, composition patterns
- Rules of hooks — why they can't be called conditionally and how the order matters
Q1.Explain the useEffect hook. What are its common pitfalls, and how do you avoid them?
useEffect lets you synchronize a component with an external system (API calls, subscriptions, DOM manipulation). It runs after the component renders.
Anatomy of useEffect:
useEffect(() => {
// Effect logic (runs after render)
return () => {
// Cleanup (runs before next effect or unmount)
};
}, [dependencies]);
Dependency array behavior:
• No array — effect runs after every render (rarely what you want)
• Empty array [] — effect runs once after mount (like componentDidMount)
• With dependencies [a, b] — effect runs when a or b changes
Common pitfalls and fixes:
• Missing dependencies — stale closures cause bugs. Always include all referenced values in the dependency array, or use the useRef escape hatch
• Object/array dependencies — objects and arrays are compared by reference. Use useMemo to stabilize references, or extract specific primitive values
• Infinite loops — setting state inside an effect that depends on that state. Use a functional state updater or restructure the logic
• Race conditions in data fetching — use a cleanup flag or AbortController to cancel stale requests
Best practice: Each effect should do one thing. Split unrelated effects into separate useEffect calls.Q2.What are custom hooks? When and how should you create one?
use and that calls other hooks. It lets you extract and reuse stateful logic across components.
When to create a custom hook:
• When two or more components share the same stateful logic
• When a component's hook logic becomes complex enough to warrant its own abstraction
• When you want to make logic testable in isolation
Example — useFetch:
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(res => res.json())
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
return () => controller.abort();
}, [url]);
return { data, loading, error };
}
Design principles for custom hooks:
• Return values the consumer needs (not internal implementation details)
• Accept configuration through parameters
• Handle cleanup properly
• Follow the naming convention — always prefix with use
Common custom hooks in production:
• useDebounce — debounce rapidly changing values
• useLocalStorage — sync state with localStorage
• useMediaQuery — respond to viewport changes
• useIntersectionObserver — lazy loading and infinite scrollQ3.Explain the difference between controlled and uncontrolled components in React.
value prop and onChange handler
• Every keystroke triggers a state update and re-render
• Ideal for: form validation, conditional disabling, formatting input as the user types
Uncontrolled components:
• The DOM itself manages the input state
• Access the value via a ref (useRef) when needed (e.g., on form submit)
• Fewer re-renders — the component doesn't re-render on every keystroke
• Ideal for: simple forms, file inputs (<input type="file"> must be uncontrolled), and integrating with non-React libraries
When to choose which:
• Default to controlled components — they give you more control and are easier to test
• Use uncontrolled components when performance matters (high-frequency updates) or when integrating with third-party DOM libraries
• React Hook Form uses uncontrolled components internally for performance, while Formik uses controlled components
Key rule: Never switch between controlled and uncontrolled during a component's lifetime — React will warn about this. Always decide upfront.State Management & Data Flow
- Component state —
useStatefor local state, lifting state up for shared state - Context API —
useContextfor avoiding prop drilling, performance considerations - External state libraries — Redux, Zustand, Jotai, and when each is appropriate
- Server state — React Query / TanStack Query for caching and synchronizing server data
Q4.When should you use React Context vs a state management library like Redux or Zustand?
React Performance Optimization
- Re-render mechanics — what triggers re-renders and how to minimize unnecessary ones
- Memoization —
React.memo,useMemo,useCallbackand when they actually help - Code splitting —
React.lazy,Suspense, and dynamic imports - Virtualization — rendering large lists efficiently with react-window or react-virtuoso
Q5.When should you use React.memo, useMemo, and useCallback? When are they unnecessary?
Frequently Asked Questions
Should I learn class components for interviews?
Understand them at a conceptual level (lifecycle methods, this binding) since you'll encounter them in legacy codebases, but focus your preparation on hooks and functional components. No modern React interview expects you to write class components — they may ask you to explain the differences or discuss migration strategies.
How deeply should I know Next.js for React interviews?
It depends on the role. For general React positions, understanding the concepts (SSR vs SSG vs ISR, file-based routing, API routes) is sufficient. For roles that specifically use Next.js, expect questions on the App Router, React Server Components, server actions, and caching strategies. Next.js knowledge is increasingly expected for senior frontend roles.
What testing approach should I be prepared to discuss?
Know React Testing Library's philosophy (test behavior, not implementation) and be able to write tests for hooks, async components, and user interactions. Understand the testing pyramid: unit tests for utilities, integration tests for component behavior, and E2E tests (Playwright/Cypress) for critical user flows. Avoid questions about enzyme — it's deprecated.
Don't freeze in your next interview
InterviewsUnlocked gives you real-time AI coaching during live interviews — role-tailored answers, follow-up cues, and confidence when you need it most.
Related Resources
JavaScript Interview Questions & Answers for All Levels
Comprehensive JavaScript interview prep covering closures, prototypes, event loop, ES6+ features, async patterns, and real-world coding challenges with expert answers.
Read moreSkills & TechnologiesCSS Interview Questions & Answers: Layout, Design, and Modern Techniques
Master CSS interviews with questions covering Flexbox, Grid, specificity, responsive design, animations, and modern CSS-in-JS approaches with detailed expert answers.
Read moreInterview QuestionsTop Frontend Developer Interview Questions & Answers
Ace your frontend developer interview with questions on JavaScript, React, CSS, web performance, accessibility, and system design with expert answers.
Read moreInterview QuestionsTop Software Engineer Interview Questions & Answers
Prepare for your software engineering interview with expert-crafted questions and detailed answers covering data structures, algorithms, system design, and behavioral topics.
Read moreInterview TipsTechnical Interview Preparation: A 4-Week Plan
A structured 4-week technical interview preparation plan covering data structures, algorithms, system design, and mock interviews with daily schedules.
Read more