Skip to content

PUBLIC QUESTION PREVIEW

React & Frontend interview questions

Hooks, state management, rendering, performance, browser fundamentals.

Showing 12 of 100 source questions. Sample answers are study material, not employer-specific hiring guidance.

How to work through this preview

Attempt each question before reading its answer. For a concept, give a definition and a concrete example. For code, state constraints, walk through a small input, and check complexity. For design, separate requirements from assumptions and explain failure handling. Use real situations for behavioral answers.

QUESTION 1 / medium / conceptual

What is the difference between useEffect and useLayoutEffect?

Sample answer

useEffect: runs asynchronously after the browser has painted. Won't block the browser — good for data fetching, subscriptions, logging. useLayoutEffect: runs synchronously after DOM mutations but BEFORE the browser paints. Blocks paint until it finishes. Use when you need to measure DOM elements or apply DOM mutations that must be done before the user sees the result (e.g., preventing layout flash, reading scroll position, tooltips). Rule of thumb: use useEffect by default. Switch to useLayoutEffect only if you see a visible flicker or need DOM measurements before paint.

Hints to guide your next attempt

  • When does each fire relative to DOM updates?
  • Synchronous vs. asynchronous after render

Source tags: react / hooks / useEffect / useLayoutEffect / rendering

QUESTION 2 / medium / conceptual

What causes unnecessary re-renders in React and how do you prevent them?

Sample answer

Causes: 1. Parent re-renders pass new object/array references as props (even if values are equal) 2. Context value changes re-render all consumers 3. State updates that produce the same value still trigger a re-render if using object references Prevention: - React.memo(Component): skips re-render if props are shallowly equal - useCallback: memoizes a function reference - useMemo: memoizes a computed value - Split context into smaller pieces so only relevant consumers update - Move state down the tree (colocate) Warning: premature optimization — measure first with React DevTools Profiler before adding memoization.

Hints to guide your next attempt

  • React re-renders when state/props change by reference
  • useMemo, useCallback, React.memo for optimization

Source tags: react / performance / memo / useMemo / re-render

QUESTION 3 / hard / conceptual

Explain React's reconciliation algorithm. What is the "diffing" process?

Sample answer

React maintains a virtual DOM. On state/prop change, it creates a new virtual tree and diffs it against the previous one (reconciliation). Rules: 1. Different element types → unmount old tree, mount new one from scratch 2. Same element type → update existing DOM node's props 3. Lists: without keys, React matches by index (can cause bugs). With keys, React matches by key — stable keys = reuse existing DOM nodes. React Fiber (v16+): reconciliation is now interruptible and prioritized. High-priority updates (user input) can interrupt low-priority ones (data fetching renders). The fiber is a unit of work — React can pause, resume, or discard fiber work.

Hints to guide your next attempt

  • React compares old and new virtual DOM trees
  • Same type = update, different type = unmount + remount
  • Keys matter for lists

Source tags: react / reconciliation / virtual-dom / fiber / diffing

QUESTION 4 / easy / conceptual

What is the difference between controlled and uncontrolled components?

Sample answer

Controlled component: form input value is tied to React state. Every keystroke calls setState. React is always in sync. <input value={name} onChange={e => setName(e.target.value)} /> Uncontrolled component: DOM manages its own state. You use a ref to read the value when needed. <input ref={inputRef} defaultValue="initial" /> Use controlled when: you need to validate on every keystroke, conditionally disable submit, format input in real-time. Use uncontrolled when: integrating with non-React code, simple one-time reads, file inputs.

Hints to guide your next attempt

  • Controlled: React state is the source of truth
  • Uncontrolled: DOM is the source of truth

Source tags: react / controlled / uncontrolled / forms / refs

QUESTION 5 / easy / conceptual

What is useState and how does functional state update work?

Sample answer

useState returns [value, setter]. When you call the setter, React schedules a re-render with the new value. Functional update — use when new state depends on previous state: setCount(prev => prev + 1); // safe even in async callbacks Why it matters: if you call setCount(count + 1) three times in a row inside a closure, all three see the same stale count. Functional form reads the latest queued state each time. React 18 automatic batching: multiple setState calls in event handlers, setTimeout, and promises are all batched into one render by default. React 17 only batched inside React event handlers. // Resetting to initial value: const [state, setState] = useState(initialValue); setState(initialValue); // full reset // Lazy initializer (runs only once): const [state, setState] = useState(() => expensiveComputation());

Hints to guide your next attempt

  • setState with a function receives the previous state
  • Batching means multiple setStates in one event = one render

Source tags: react / hooks / useState / batching

QUESTION 6 / medium / conceptual

When should you use useReducer instead of useState?

Sample answer

useReducer is preferable over useState when: 1. State has multiple sub-values that change together 2. Next state depends on previous state in complex ways 3. You want to centralise and test state transition logic const reducer = (state, action) => { switch (action.type) { case 'INCREMENT': return { ...state, count: state.count + 1 }; case 'RESET': return { ...state, count: 0 }; case 'SET_NAME': return { ...state, name: action.payload }; default: return state; } }; const [state, dispatch] = useReducer(reducer, { count: 0, name: '' }); dispatch({ type: 'INCREMENT' }); dispatch({ type: 'SET_NAME', payload: 'Ravin' }); Benefits over useState: - Reducer is a pure function — unit test without React - dispatch reference is stable — safe to pass as prop without useCallback - Logic lives in one place, not spread across handlers

Hints to guide your next attempt

  • useReducer is better for complex state transitions
  • Reducer makes state logic testable in isolation

Source tags: react / hooks / useReducer / state-management

QUESTION 7 / medium / conceptual

How does useContext work and what are its performance pitfalls?

Sample answer

useContext subscribes a component to a context value. When the context value changes, ALL consumers re-render — even if they only use part of the value. const ThemeContext = createContext('light'); function App() { return ( <ThemeContext.Provider value="dark"> <Child /> </ThemeContext.Provider> ); } function Child() { const theme = useContext(ThemeContext); // re-renders whenever value changes } Performance pitfalls: 1. Putting a new object as context value on every render: <Context.Provider value={{ user, setUser }}> // new object = all consumers re-render Fix: useMemo({ value: useMemo(() => ({ user, setUser }), [user]) }) 2. Large monolithic context (auth + theme + cart in one): Any change re-renders all consumers. Fix: split into AuthContext, ThemeContext, CartContext 3. Context is not a replacement for state management — no selector support. If component only needs user.name but not user.cart, it still re-renders when cart changes. Fix for this: Zustand selectors or splitting context further.

Hints to guide your next attempt

  • Every context consumer re-renders when context value changes
  • Split contexts by update frequency

Source tags: react / hooks / useContext / context / performance

QUESTION 8 / easy / conceptual

What is useRef used for? What are the two main use cases?

Sample answer

useRef returns a mutable object { current: initialValue }. Changing .current does NOT trigger a re-render. Use case 1 — DOM access: const inputRef = useRef(null); <input ref={inputRef} /> inputRef.current.focus(); // imperative DOM manipulation Use case 2 — Mutable instance variable (persists across renders, no re-render on change): const timerRef = useRef(null); timerRef.current = setTimeout(fn, 1000); // clear without stale closure issues clearTimeout(timerRef.current); // Tracking previous value: const prevCount = useRef(count); useEffect(() => { prevCount.current = count; }); // runs after render Common mistakes: - Don't read/write ref.current during render (causes inconsistency) - Don't use ref when you need the component to re-render on change — use state instead - ref.current is null until the component mounts

Hints to guide your next attempt

  • DOM access and mutable values that do not trigger re-render

Source tags: react / hooks / useRef / dom

QUESTION 9 / medium / conceptual

How do useMemo and useCallback work? When are they actually worth using?

Sample answer

useMemo: memoises a computed value. Re-runs only when dependencies change. const sorted = useMemo(() => items.slice().sort(), [items]); useCallback: memoises a function reference. Re-creates only when dependencies change. const handleClick = useCallback(() => doSomething(id), [id]); When they're actually worth it: 1. Passing a callback to a React.memo child — without useCallback, the child re-renders on every parent render because the function is a new reference each time. 2. useMemo for genuinely expensive calculations (sorting 10k items, heavy transforms). 3. Stable references needed as useEffect dependencies. When they're NOT worth it: - Simple primitives (useMemo(() => a + b, [a, b]) — just write a + b) - Components that aren't wrapped in React.memo — memoising the prop is pointless - Memoising cheap operations — the memo overhead can cost more than the calculation Rule: measure with React DevTools Profiler before adding memoisation.

Hints to guide your next attempt

  • useMemo caches a value; useCallback caches a function
  • Only worth it when the child is wrapped in React.memo

Source tags: react / hooks / useMemo / useCallback / performance

QUESTION 10 / medium / conceptual

What are custom hooks? What rules must you follow when writing them?

Sample answer

A custom hook is a JavaScript function whose name starts with "use" and that calls other hooks. It lets you extract and reuse stateful logic without changing component hierarchy. // Custom hook for fetching data: function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; setLoading(true); fetch(url) .then(r => r.json()) .then(d => { if (!cancelled) { setData(d); setLoading(false); } }) .catch(e => { if (!cancelled) { setError(e); setLoading(false); } }); return () => { cancelled = true; }; }, [url]); return { data, loading, error }; } // Usage: const { data, loading, error } = useFetch('/api/users'); Rules of Hooks (apply to custom hooks too): 1. Only call hooks at the top level — never inside loops, conditions, or nested functions 2. Only call hooks from React functions or other custom hooks 3. Name must start with "use" — React linting tools enforce this Examples of good custom hooks: useDebounce, useLocalStorage, useOnClickOutside, useWindowSize, useIntersectionObserver

Hints to guide your next attempt

  • Custom hooks extract reusable stateful logic
  • Must start with "use" and can call other hooks

Source tags: react / custom-hooks / hooks / patterns

QUESTION 11 / medium / conceptual

What is React.memo? How is it different from useMemo?

Sample answer

React.memo is a Higher Order Component that wraps a component and skips re-rendering if its props are shallowly equal to the previous render's props. const Button = React.memo(({ label, onClick }) => { return <button onClick={onClick}>{label}</button>; }); // Button only re-renders if label or onClick reference changes Custom comparison: const Button = React.memo(({ user }) => <div>{user.name}</div>, (prev, next) => { return prev.user.id === next.user.id; // return true = skip re-render }); Difference from useMemo: - React.memo: memoises a COMPONENT (skips render if props unchanged) - useMemo: memoises a VALUE inside a component Common mistake: wrapping a component in React.memo but passing a new function/object prop every render — the shallow comparison fails and the component re-renders anyway. Fix: combine with useCallback for function props. When NOT to use React.memo: - Components that almost always receive new props - Very cheap renders (the comparison itself has a cost) - Components with children prop (children is a new React element each render)

Hints to guide your next attempt

  • React.memo is for components; useMemo is for values
  • React.memo does shallow prop comparison by default

Source tags: react / memo / performance / optimization

QUESTION 12 / medium / conceptual

What are Error Boundaries? How do you implement one?

Sample answer

Error boundaries catch JavaScript errors in the render tree below them and display a fallback UI instead of crashing the whole app. They must be class components (no hook equivalent yet). class ErrorBoundary extends React.Component { state = { hasError: false, error: null }; static getDerivedStateFromError(error) { return { hasError: true, error }; } componentDidCatch(error, info) { logErrorToService(error, info.componentStack); } render() { if (this.state.hasError) { return <h2>Something went wrong.</h2>; } return this.props.children; } } // Usage: <ErrorBoundary> <MyComponent /> </ErrorBoundary> What they do NOT catch: - Errors in event handlers (use try/catch there) - Async errors (setTimeout, fetch) - Errors in the error boundary itself - Server-side rendering errors react-error-boundary library provides a functional wrapper with reset capability: <ErrorBoundary FallbackComponent={ErrorFallback} onReset={reset}>

Hints to guide your next attempt

  • Error boundaries must be class components
  • They catch errors in the render phase, not in event handlers

Source tags: react / error-boundary / class-components / error-handling

Check understanding, not recognition

  • Can you explain the answer without reading it?
  • Can you show when the approach fails or needs a different assumption?
  • Can you connect the concept to a real project, task, or decision you have made?
  • Can you distinguish a simplified interview example from a production requirement?

A LITTLE MORE CLARITY

Frequently asked questions

How many React & Frontend questions are shown here?

This public preview shows 12 questions with the supplied answers from the app's 100-question React & Frontend bank. Full interactive practice requires signing in.

Should I memorize the sample answers?

Use them as reference explanations, not a script or a guarantee of technical correctness for every environment. Explain your assumptions, validate code against your language and version, and discuss trade-offs. Behavioral answers should be built from your own experience.

What do hints and solution steps mean?

Hints identify ideas to consider before reading the answer. When the source question includes steps, they are shown as a separate walkthrough. Example capacities and design targets in a solution are assumptions for that exercise, not real system statistics.

BUILD YOUR NEXT OPPORTUNITY

Practice React & Frontend actively.

Sign in to use the full topic bank and interactive practice workspace.

Open Topic Practice