All categories

Category

React

Hooks, Fiber, concurrent rendering, hydration, and performance.

218 questions

218 of 218
React
Easy
What is the difference between a React Node, Element, and Component?

A **Component** is the function or class you write (`function Button(){...}`). A **React Element** is a plain object describing what to render — what `<Button />` evaluates to: `{ type: Button, props: {...}, key, ref }`. A **React Node** is anything renderable: an element, a string, a number, null, false, or an array of these.

6 min
React
Medium
What is JSX and how does React render elements from it?

JSX is syntactic sugar over React.createElement(type, props, ...children). The compiler (Babel/SWC/esbuild) transforms <div className='x'>hi</div> into createElement('div', { className: 'x' }, 'hi'), which returns a plain object describing the element. React's reconciler walks this tree, diffs against the previous tree, and applies minimal DOM mutations. JSX is not HTML and not a template engine — it's JavaScript expressions.

6 min
React
Easy
What is the difference between React.createElement and React.cloneElement?

React.createElement(type, props, ...children) creates a brand-new element from scratch — JSX compiles to it. React.cloneElement(element, props, ...children) copies an EXISTING element, shallow-merging new props over its original ones. cloneElement is for injecting props into children you received.

4 min
React
Medium
What are React Fragments and why would you use them?

Fragments let a component return multiple elements without an extra wrapper DOM node. `<>...</>` (shorthand) or `<Fragment>...</Fragment>` (explicit, accepts a `key` prop). Use them to avoid unnecessary divs that break CSS Grid/Flexbox layouts, to keep tables valid, and to return sibling elements from map callbacks.

4 min
React
Medium
What are React Portals and when would you use them?

Portals render a child into a DOM node outside the parent's hierarchy while preserving React's component tree (state, context, events). Used for modals, tooltips, popovers, toasts — anything that needs to escape `overflow:hidden` or stacking context but stay logically inside the component. Events still bubble through React's virtual tree, not the DOM ancestor.

3 min
React
Medium
What is React Strict Mode and how does it affect development?

Strict Mode is a dev-only React wrapper that surfaces unsafe patterns: double-invokes components/effects/state initializers, warns on deprecated APIs (legacy refs, findDOMNode), forbids side-effects in render. The double-mount in React 18 specifically reveals missing useEffect cleanups. Production is unchanged. Always wrap the app in <StrictMode> during development.

3 min
React
Easy
What is the difference between ReactDOM.render and createRoot in React 18?

`ReactDOM.render(<App/>, root)` is the legacy synchronous API (React 16/17). `createRoot(root).render(<App/>)` is the React 18 API that enables concurrent features: automatic batching everywhere, useTransition, useDeferredValue, streaming SSR, Suspense for data. Functionally similar for simple apps but createRoot unlocks the new scheduler. ReactDOM.render still works in 18 but logs a deprecation warning.

6 min
React
Easy
What are the key differences between React 16 and React 18?

React 18 added concurrent rendering (interruptible renders), automatic batching everywhere (not just in event handlers), Suspense for data fetching, useTransition / useDeferredValue, useId, the new createRoot API, server components (experimental), and stricter StrictMode that double-mounts effects in dev. React 16 introduced Fiber, hooks (16.8), and error boundaries but rendering was fully synchronous.

7 min
React
Medium
How did React improve performance compared to Angular?

Smaller runtime (~45 KB gzipped vs Angular's larger framework), simpler change detection (re-render on state change vs zone.js patching async APIs), virtual DOM diffing instead of dirty-checking template bindings, hooks-based composition, tree-shakeable, and a leaner mental model that's faster to optimize. Caveat: well-built Angular apps can be very fast; framework choice rarely dominates real-world perf.

7 min
React
Medium
Why would you migrate from Angular to React, and what challenges have you faced?

Reasons: smaller bundle, larger ecosystem/hiring pool, simpler mental model (no DI, no decorators, no NgModules), faster iteration. Challenges: re-implementing two-way binding with controlled inputs, replacing RxJS with React Query/Zustand, migrating dependency injection patterns, rebuilding form validation, and the team learning JSX + the 'thinking in React' model.

8 min
React
Easy
What are the limitations of React when building large scale applications?

React is a view library, not a framework — no built-in routing, data fetching, forms, or state management. The team picks N libraries; mismatches and version drift accumulate. Out-of-box bundle is small but unguided architecture leads to bloat. No conventions for folder structure, code splitting, SSR — different shops solve it differently. Performance is up to the developer. Hooks rules + closures are easy to get wrong. RSC is still maturing.

9 min
React
Easy
What are the differences between functional and class components in React?

Functional components are plain functions that return JSX and use hooks for state/effects/refs — the modern default. Class components extend Component, use this.state / setState, and have lifecycle methods. Functional components are smaller, easier to test, free of 'this' binding bugs, and the only path to new React features (concurrent rendering, Server Components). Use class components only for error boundaries.

6 min
React
Easy
How do class lifecycle methods map to useEffect in React?

Class lifecycles split a single concern across multiple methods (`componentDidMount` + `componentDidUpdate` + `componentWillUnmount`). `useEffect` lets you co-locate the whole effect — setup + cleanup — and run it whenever its dependencies change. Effects are about synchronization, not lifecycle moments.

4 min
React
Medium
How does React handle the component lifecycle in functional components?

Function components don't have lifecycle methods — they re-run top-to-bottom on every render. Hooks emulate the lifecycle: useState/useRef = instance fields; useEffect with [] = componentDidMount + componentWillUnmount; useEffect with deps = componentDidUpdate; useLayoutEffect = synchronous post-commit work; the function body itself = render. Reasoning shifts from 'phases' to 'this state at this moment'.

6 min
React
Easy
What is the difference between state and props in React?

Props are inputs passed into a component by its parent — read-only from the component's view. State is data the component owns and manages internally, and can change over time. Props flow down and are immutable; state is local, mutable (via setState), and triggers re-renders.

5 min
React
Easy
What is the difference between props and state in React?

Props are inputs passed in from a parent — read-only inside the component. State is internal, mutable via `setState`. Props flow down; events flow up. If multiple components need the same value, lift it to the lowest common parent and pass it down as a prop. If a piece of data can be derived from props, don't put it in state.

4 min
React
Medium
How do state updates and re renders work in React?

setState schedules a re-render; React reconciles the virtual DOM, diffs vs the previous render, and commits changes to the real DOM. Updates batch automatically (React 18+) across sync and async code. A component re-renders when its state, props, or subscribed context changes; parent re-render cascades to children unless React.memo + stable props short-circuit it. Updates from outside React (Redux, Zustand) need useSyncExternalStore for tearing-free concurrent rendering.

9 min
React
Medium
Why should you avoid mutating state directly in React?

React detects changes by reference (Object.is) — mutating state in place keeps the same reference, so React doesn't know it changed and skips the re-render. Mutation also breaks memo/PureComponent, corrupts previous-state snapshots, and makes time-travel/debugging unreliable. Always create a new object/array.

4 min
React
Easy
How do you write immutable state updates in React?

Always produce new references for changed branches: `{...state, field: newValue}`, `state.map(...)`, `state.filter(...)`. For nested updates, replace the whole path (`{...state, a: {...state.a, b: 1}}`). Use Immer (`produce`) for ergonomic mutable-syntax-but-immutable-output, or RTK's createSlice which bakes it in.

3 min
React
Easy
What is state scheduling in React and how does it work?

State scheduling is how React decides WHEN to actually apply a state update and re-render. React 18 introduced automatic batching (multiple setState calls in a single tick collapse to one render) and priority-based scheduling: urgent updates (clicks, input) run synchronously; non-urgent updates wrapped in startTransition can be deferred or interrupted by higher-priority work.

7 min
React
Medium
What is state colocation in React and why does it matter?

Put state as close as possible to where it's used. The wrong default — 'lift everything to App' — re-renders the whole tree for any change and obscures ownership. Colocation: input state in the input, modal-open state in the modal trigger, filter state in the filter panel. Lift only when multiple siblings need it; even then, lift to the lowest common ancestor.

4 min
React
Easy
What is prop drilling in React and how do you avoid it?

Passing props through multiple intermediate components that don't use them, just to reach a deep descendant. It makes code verbose, tightly couples components, and is fragile to refactor. Fixes: Context, composition (children/slots), or a state library — pick by how the data is used.

4 min
React
Easy
What are the common conditional rendering patterns in React?

Patterns: `&&` for show-or-hide, ternary for either-or, early return for guards, switch/lookup for many cases, render prop for conditional content with shared logic, Suspense/ErrorBoundary for loading/error. Avoid `&&` with a numeric `0` (renders "0"). Hoist branches into named components when JSX gets dense.

3 min
React
Medium
Why do we need keys in React lists?

Keys give React a stable identity for each item across renders. Without them React falls back to index-based matching, which corrupts state when items are inserted, removed, or reordered. A row keyed by index would 'inherit' the input value of whatever item used to be in that position. Use a stable id from your data; avoid array index when the list mutates.

6 min
React
Easy
Why do React keys matter and what happens when you get them wrong?

Keys give React identity for siblings in a list. Without stable keys, React matches children by position — reordering or inserting mid-list causes wrong component reuse: state, DOM, refs, and focus follow the slot, not the data. Use a stable, unique id from the data; never the array index unless the list is append-only and uneditable.

5 min
React
Medium
Why do React keys matter, and how do bad keys break applications?

Keys give list items a stable identity so React's reconciler can match elements across renders. Good keys = correct minimal updates. Bad keys (index, or random each render) cause wrong state/DOM reuse, lost focus and input values, broken animations, and unnecessary re-renders.

4 min
React
Medium
Why do array indices make bad keys in React lists?

An index isn't tied to the item — it's tied to the position. Insert, delete, reorder, or filter the list and the same index now points to different data, so React reuses the wrong DOM node and component state: wrong input values, misplaced focus, stale state, broken animations. Use a stable id.

4 min
React
Easy
How does event handling work in React, and how does it differ from native DOM events?

React wraps native DOM events in a SyntheticEvent for cross-browser consistency. Attach handlers as JSX props (`onClick`, `onChange`) — camelCase, function reference, not a string. Since React 17, events are delegated to the React root, not `document`. Call `e.preventDefault()` / `e.stopPropagation()` on the synthetic event. For some events React doesn't expose (focus visible, native scroll passive listeners), use `addEventListener` in a `useEffect`.

5 min
React
Medium
How does React handle event delegation under the hood?

Since React 17, React attaches one listener per event type at the **app root** (the container you passed to `createRoot`), not at `document`. Events bubble up; React's synthetic event system reconstructs the event, walks the React tree, and fires the appropriate `onClick` handlers. `onClickCapture` runs in capture phase. `stopPropagation` on a synthetic event only stops React listeners, not native ones.

4 min
React
Medium
What are React synthetic events and how do they differ from native DOM events?

React wraps native DOM events in a cross-browser `SyntheticEvent` shim. Same API (`preventDefault`, `stopPropagation`, `target`) but normalized. React 17+ attaches listeners at the **root container**, not `document`; events bubble up through React's tree. Differences from native: no event pooling since React 17; `onChange` fires on every keystroke; `onScroll` doesn't bubble; some events use capture phase.

4 min
React
Medium
What are React hooks and how do you create custom hooks?

Hooks are functions starting with `use` that let function components opt into React features (state, effects, context, refs). A custom hook is just a function that calls other hooks — naming convention `useXxx` enables the linter to enforce the rules of hooks. Extract reusable stateful logic by composing built-in hooks into a function.

6 min
React
Medium
Can you explain the most important React hooks you use day to day?

The five hooks that cover 95% of component code: useState (local reactive state), useEffect (subscriptions/side-effects with cleanup), useRef (mutable values that survive re-renders + DOM access), useMemo (cache an expensive value across renders), useCallback (cache a function identity for memoized children).

7 min
React
Medium
How do you manage state in React using useState and useReducer?

useState fits 1–3 independent values updated with simple setters. useReducer fits state with multiple related fields or complex transitions — pull the update logic into a pure reducer (state, action) → state. Reducers are easier to test, easier to log, and naturally handle multi-step state machines. Reach for useReducer when setState calls start to multiply or several pieces of state must change together.

7 min
React
Medium
Can you explain the lifecycle of the useEffect hook?

useEffect runs AFTER React commits to the DOM. The setup function runs when deps change (or on mount if deps are empty). The cleanup returned from setup runs BEFORE the next setup AND on unmount. Missing deps cause stale closures; mutable deps cause infinite loops; effects that mutate refs don't trigger re-renders.

7 min
React
Medium
How does the useEffect lifecycle work in practice?

useEffect runs AFTER React commits to the DOM. Setup function runs when deps change or on mount; cleanup runs before next setup AND on unmount. Phase: render → commit → useLayoutEffect (sync) → browser paint → useEffect (async). StrictMode dev double-invokes effects to surface missing cleanups. Common bugs: stale closures (use functional updaters), infinite loops (use derived render), missing cleanups (return cleanup function).

7 min
React
Medium
How do you use useEffect to fetch data from an API in React?

useEffect runs after render, making it the classic place to fetch data on mount or when dependencies change. You manage loading/error/data state, clean up to avoid race conditions and setState-after-unmount, and re-fetch when deps change. But for real apps, prefer React Query/SWR or framework data loading.

6 min
React
Medium
Why do we need the dependency array in useEffect?

The dependency array tells React WHEN to re-run the effect — it compares deps between renders and re-runs only if one changed. No array = every render; []= once on mount; [a,b] = when a or b changes. It also defines which values the effect 'sees'; omitting deps causes stale closures or infinite loops.

4 min
React
Easy
How would you debug a React snippet where useEffect is not behaving as expected?

Common causes: missing dependency (stale closure, value never updates), wrong dep array shape ([] when should be [x]), running twice in dev (Strict Mode, intentional), effect setting state that triggers the same effect (infinite loop), depending on object/function literal that's new every render (always re-fires), forgetting cleanup (subscriptions accumulate), async work without abort (race conditions). Use the react-hooks/exhaustive-deps lint rule + React DevTools Profiler.

9 min
React
Medium
How does React handle circular dependencies in useEffect?

It doesn't — circular useEffect dependencies cause infinite re-renders. Typical bug: effect writes to state that's in its own dep array, triggering itself. Fixes: (1) use functional updaters `setX(prev => ...)` to read latest state without depending on it, (2) move the derived value into useMemo computed in render, (3) use refs for values that should not trigger re-runs, (4) reset state via `key` prop instead of effect-driven sync.

7 min
React
Medium
When should you avoid reaching for useEffect in React?

Don't use useEffect for: deriving state (compute during render); transforming data for rendering (compute or useMemo); responding to user events (do it in the handler); resetting state on prop change (use a `key`); chaining state updates (combine into one). Effects are for *synchronizing with external systems* — DOM, subscriptions, APIs — not for in-app data flow.

5 min
React
Medium
What is the difference between useEffect and useLayoutEffect, and when do you use each?

`useEffect` runs after the browser paints — async, doesn't block visual updates. `useLayoutEffect` runs synchronously after the DOM mutates but BEFORE paint — use it when you need to measure layout and mutate the DOM before the user sees anything. Default to `useEffect`; reach for `useLayoutEffect` only for measure-and-adjust patterns (tooltips, animations from a measured position).

5 min
React
Medium
How does React handle side effects, and how do you manage them effectively?

Side effects (DOM mutation, network, subscriptions, timers, logging) live in useEffect — runs after commit, returns cleanup. Pure render = no side effects. Manage by: (1) keeping effects small and focused, (2) cleaning up properly, (3) avoiding state-from-state in effects (use derived render or key reset), (4) reaching for React Query for fetches, (5) using refs for non-reactive values. StrictMode dev double-mount surfaces missing cleanups.

8 min
React
Medium
Why do we need the useRef hook in React?

`useRef` stores a mutable value that persists across renders without triggering re-renders. Two main uses: (1) hold a reference to a DOM node (`ref={ref}`) for measurement/focus/imperative ops, (2) store any mutable value (timer ids, latest values, previous props) that shouldn't cause re-renders. `.current` is the only field; updating it is intentional, not a state change.

3 min
React
Medium
When should you use refs instead of state in React?

Refs for values that need to persist across renders but **don't drive rendering**: DOM nodes, timer/interval ids, mutable counters, latest-value mirrors for stale-closure fixes, third-party instances. State for values that, when changed, must trigger a re-render. Mutating a ref doesn't re-render; setting state does. Don't read/write refs during render — only in effects and handlers.

4 min
React
Medium
What does forwardRef do in React, and when would you reach for useImperativeHandle?

`forwardRef` forwards a ref through a component so parents can access the underlying DOM node or imperative API. `useImperativeHandle` customizes what the ref exposes — handy when you need to expose specific methods (`focus`, `scrollIntoView`, `open()`) without leaking the DOM node. In React 19, regular function components accept ref as a prop, removing the need for forwardRef.

3 min
React
Medium
How does the useImperativeHandle hook work in React, and when do you use it?

Used with forwardRef, useImperativeHandle(ref, createHandle, deps) lets a child customize the value the parent's ref points to — exposing a curated API ({ focus, reset }) instead of the raw DOM node. It runs during commit. It's an escape hatch — prefer declarative props when possible.

4 min
React
Medium
How would you expose a child component's API to its parent in React?

Prefer declarative props (controlled value + event callbacks) over imperative APIs. When imperative access is genuinely needed (focus, scroll, play), expose a minimal, intentional handle via forwardRef + useImperativeHandle. Compound components for structural APIs.

6 min
React
Easy
What is the difference between useMemo and useCallback, and when do you use each?

`useMemo(fn, deps)` caches the *return value* of `fn`. `useCallback(fn, deps)` caches the *function itself*. `useCallback(fn, d)` is exactly `useMemo(() => fn, d)`. Use them for referential stability of values/functions passed to memoized children, and for genuinely expensive computations. In React 19+, the React Compiler handles most of these automatically.

5 min
React
Medium
How does React.memo differ from useMemo and useCallback?

React.memo: HOC that prevents a component from re-rendering when its props are shallow-equal to the previous render. useMemo: caches a COMPUTED VALUE across renders, recomputes when deps change. useCallback: caches a FUNCTION reference across renders, returns same function when deps unchanged. React.memo is about whether a child renders; useMemo/useCallback are about whether passed values change reference. Use together: memoized child + stable callback/value props.

7 min
React
Medium
How have you used React.memo, useCallback, useMemo, and other optimization techniques in your projects?

Yes — but selectively. `React.memo` for genuinely expensive children with stable prop references. `useCallback` for callbacks passed to memo'd children or as effect deps. `useMemo` for measurable expensive derivations. Other levers: virtualization, code splitting, `useDeferredValue`/`startTransition`, Suspense, Server Components. Profile first; the default of nothing is right most of the time.

4 min
React
Medium
How does React manage re renders using React.memo, useMemo, and useCallback?

React re-renders on state change, parent re-render, context change, or external store update. Tools to prevent unnecessary renders: `React.memo(Component)` skips re-render when props are referentially equal; `useMemo(fn, deps)` caches a computed value across renders; `useCallback(fn, deps)` caches a function reference so memoized children don't bail. Combined: memoize the child, pass useCallback handlers, useMemo objects. Profile first — most uses are unnecessary.

7 min
React
Medium
When does memoization help and when does it hurt React performance?

Memoization (memo/useMemo/useCallback) helps when it prevents an expensive computation or a costly subtree re-render, AND the deps are actually stable. It hurts when the work is cheap, deps change every render, or you wrap everything reflexively — then you pay comparison + memory cost for nothing.

5 min
React
Medium
How do you decide which React components actually need memoization?

Memoize a component when it re-renders often (parent re-renders frequently), its props are stable or can be made stable, and its render is non-trivial. Don't memoize cheap components, ones whose props change every render anyway, or as a blanket policy. Always profile first.

6 min
React
Medium
What is the difference between shallow and deep comparison in React's shouldComponentUpdate?

Shallow comparison checks reference equality for objects/arrays and value equality for primitives — what React.memo and PureComponent do by default. Deep comparison walks every nested key recursively. Shallow is cheap (O(top-level props)) but misses changes inside nested objects; deep catches everything but is O(size of tree) and can be slower than re-rendering. Use shallow + immutability discipline; reach for deep only with cause.

6 min
React
Medium
How do state and refs behave inside a useCallback hook?

useCallback memoizes a function so its reference is stable across renders — unless a dependency changes. Closures inside it capture values from the render where it was created; stale deps mean stale values. The function identity matters for child memoization and effect deps.

4 min
React
Medium
How would you implement custom hooks to abstract reusable logic in React?

A custom hook is a function named `useXxx` that calls other hooks. Extract reusable stateful logic by composing built-ins: useState, useEffect, useRef, etc. Parameterize inputs, return a stable shape (`{ data, loading, error }` or `[value, setter]`), use useCallback for returned functions, document the contract. Examples: useDebounced, useFetch, useLocalStorage, useMediaQuery.

7 min
React
Medium
How would you make a custom React hook reusable across many different components?

Design custom hooks like small libraries: parameterize all inputs, return a stable shape ({ data, loading, error, refetch }), keep side-effects (subscriptions, listeners) inside with cleanup, avoid hard-coding UI concerns or context dependencies, document the contract, and write tests with @testing-library/react's renderHook.

6 min
React
Easy
How would you implement a custom React hook that debounces an input value?

`useDebouncedValue`: returns a value that updates only after the input has stopped changing for N ms. Implement with `useState` + `useEffect` (set timer on value change, clear on cleanup). Useful for search-as-you-type. Distinct from `useDeferredValue` (React 18) which is concurrent-mode aware and yields to interaction.

3 min
React
Easy
How would you implement a custom useDebounce hook from scratch?

Two flavors: `useDebouncedValue(value, delay)` returns the latest value after the input has been stable for `delay` ms — built with `useState` + `useEffect` setTimeout cleanup. `useDebouncedCallback(fn, delay)` returns a stable function that delays its invocation — built with `useRef` for the timer and `useRef` for the latest fn so closures stay fresh.

5 min
React
Easy
What is the difference between controlled and uncontrolled components in React?

Controlled = React state owns the value (`value={x}` + `onChange`). Uncontrolled = DOM owns the value, read via `ref.current.value` or on submit. Controlled wins for live validation, conditional logic, complex forms. Uncontrolled is faster and simpler for plain forms that just submit once. Don't mix the two on the same input.

5 min
React
Medium
How do you handle forms and validation in React?

For non-trivial forms, use `react-hook-form` + `zod`. RHF uses uncontrolled inputs under the hood (no re-render per keystroke), Zod owns the schema (single source of truth for types + runtime validation). Validate on blur for individual fields and on submit for the whole form. Accessibility: associate errors to fields with `aria-describedby`; focus the first invalid field on submit failure. Always re-validate on the server.

8 min
React
Easy
How do you design good validation UX in complex forms?

Validate at the right moments (on blur / on submit, then on change once a field is touched/errored), show clear inline messages near the field, never block typing, surface a submit-time summary, mirror server validation, and make errors accessible (aria-invalid, aria-describedby, focus management).

6 min
React
Medium
What are Higher Order Components in React and how are they used?

A Higher-Order Component is a function that takes a component and returns a new component with extra behavior — `withAuth(Component)`, `connect(mapStateToProps)(Component)` (Redux). Used for cross-cutting concerns: auth, logging, theming, data fetching. Largely replaced by custom hooks (cleaner composition, no wrapper hell). Still useful for: passing refs through, wrapping all instances uniformly, adapting class components.

7 min
React
Easy
What are Higher Order Components in React and when do you use them?

A HOC is a function that takes a component and returns an enhanced one (`withFoo(Component)`). Useful for cross-cutting concerns: auth, logging, theming, data fetching. Mostly superseded by hooks (cleaner, no prop-namespace pollution, no 'wrapper hell'). Still appropriate for: HOCs that operate at the component-tree level (auth gating, error boundaries with HOC API, code splitting).

4 min
React
Easy
What is the render props pattern in React and when do you use it?

Render props: a component takes a function as a child (or prop) and calls it with internal state. `<Mouse>{({x, y}) => <p>{x}</p>}</Mouse>` — the consumer decides what to render. Pre-hooks pattern for sharing logic. Mostly replaced by custom hooks; still useful for inversion of control (forms, drag, headless UI).

3 min
React
Easy
What is Redux, and how do you create a Redux Toolkit slice?

Redux is a predictable global state container based on a single store, read-only state, and pure reducers updating state via dispatched actions. Modern Redux uses Redux Toolkit: createSlice generates the reducer + action creators with Immer-powered 'mutating' syntax.

6 min
React
Medium
How would you implement the React Context API for a real feature?

createContext returns a { Provider, Consumer }. The Provider wraps a subtree with a value prop; descendants read via useContext(MyContext). Internally React walks up the fiber tree on read to find the nearest Provider; subscribers are tracked so they re-render when value changes. Pitfalls: every value change re-renders every consumer (split contexts), inline object values cause unnecessary updates (memoize).

7 min
React
Medium
How can the React Context API be used for state management?

Context API can act as lightweight global state for rarely-updated values (auth, theme, locale). Combine with useReducer for action-based updates. Split contexts by update frequency to limit re-renders. Memoize the Provider value. NOT a substitute for Redux/Zustand when state updates often or many components subscribe — Context re-renders every consumer on every value change.

7 min
React
Medium
How would you pass data between sibling components in React without using Redux?

Lift state up to the nearest common parent and pass via props. For widely-shared state across many siblings: Context API. For frequent updates with selectors: Zustand / Jotai. For server state shared between components: React Query (same cache key). For URL-driven sharing: search params via useSearchParams. For cross-tab: localStorage events or BroadcastChannel.

7 min
React
Easy
What is the difference between Redux and Redux Toolkit?

Redux is the original predictable state container — verbose: hand-write action types, action creators, reducers, immutable updates. Redux Toolkit (RTK) is the official, batteries-included wrapper: `createSlice` autogenerates actions+reducers, Immer lets you 'mutate' state in reducers, `configureStore` adds DevTools + thunk by default, RTK Query handles server state. Use RTK — plain Redux is legacy.

7 min
React
Medium
How would you implement Redux Toolkit in a React application?

RTK collapses Redux boilerplate: `createSlice` (reducers + actions in one place with Immer), `configureStore` (middleware + devtools wired), `createAsyncThunk` (async lifecycle), `createEntityAdapter` (normalized CRUD), RTK Query (React-Query-like data layer over Redux). Reduces boilerplate ~70% vs hand-rolled Redux.

5 min
React
Medium
How do you subscribe to a Redux store from a React component?

In React you don't call store.subscribe directly — useSelector subscribes a component to the slice it reads and re-renders it on change. Under the hood the <Provider> and useSelector use store.subscribe. Vanilla Redux exposes store.subscribe(listener) returning an unsubscribe function.

4 min
React
Medium
How do thunk based API calls work in Redux and how does caching behave?

Redux thunk = action creators return a function (thunk) instead of an action object. The function gets (dispatch, getState), does async work (fetch), dispatches start/success/failure actions. Caching is manual: check getState() for existing data, skip the call if fresh. No built-in dedup, TTL, or invalidation. RTK Query is the modern replacement — it gives you the cache layer thunks don't have.

7 min
React
Easy
What are the trade offs between Redux, Zustand, and Context for state management?

Context: built-in, no extra deps, but every consumer re-renders on any value change — best for low-frequency cross-tree config (theme, auth user). Redux/RTK: predictable + devtools + middleware ecosystem, opinionated boilerplate, best for complex client domains. Zustand: minimal API, selector-based subscriptions, ~1kb, best default for small/medium apps. Server state? None of these — use React Query.

5 min
React
Medium
Can React Hooks fully replace Redux for state management? Why or why not?

Often yes, but not always. For most apps: useState + Context + React Query covers 90% of what people used Redux for (server state goes to React Query, local to useState, cross-tree config to Context). What Redux still offers: time-travel devtools, middleware ecosystem (logger, sagas, listeners), strict action-based mutation pattern useful for large teams. For complex client domains with many cross-feature interactions, RTK still earns its place.

4 min
React
Medium
How do you manage global state efficiently in a React application?

Separate concerns. Server state (API responses) → React Query / RTKQ / SWR (caching, dedup, invalidation). Client global state (theme, auth, feature flags) → Context for rarely-changing values, Zustand/Jotai for frequently-changing. URL state → router params. Local state → useState. Don't put everything in one big global store; split by domain. Avoid Context for high-frequency updates — every consumer re-renders. Use selectors / atomization for granular subscription.

9 min
React
Easy
What are the best practices for managing state in large React applications?

Categorize state first: server (React Query), local UI (useState), cross-tree config (Context), cross-tree app state (Zustand/Redux with selectors), URL state (router), form state (RHF). Colocate where possible. Selectors > raw access. Feature-scoped slices with ownership in multi-team apps. Don't mirror server state in a client store. Avoid Context for hot state.

5 min
React
Medium
What is your strategy for managing global state efficiently in a React app with multiple teams contributing?

Separate kinds of state first: server state → React Query; local UI → useState; cross-tree config (theme, auth) → Context; cross-tree app state (cart, editor) → Zustand or Redux Toolkit with selector subscriptions; URL state → router. With multiple teams: shared store package, feature-scoped slices, RFCs for additions, store namespacing to prevent collisions, devtools, and clear ownership.

5 min
React
Medium
For a dashboard where chart updates, notifications, and data fetches happen independently, how would you use React Context and custom hooks?

Treat each concern as an independent slice with its own data source and hook. Charts: useChartData (React Query, polling or WebSocket). Notifications: useNotifications (subscribed via Context or external store). Data fetches: useQuery per resource. Compose at the page level. Context only for cross-cutting state (theme, auth). External libs (Zustand) when state must update at high frequency or across many consumers without re-render storms.

8 min
React
Medium
How do error boundaries enable crash recovery in React?

Error boundaries catch render errors in the subtree below them and show a fallback. Place one at the app root (last line of defense), one per route, and one per significant widget (chart, table, embed) so one crash doesn't take down the page. Pair with global window error handlers for unhandled promise rejections, and a logger (Sentry) to capture stack + componentStack + user context.

8 min
React
Medium
How do you prevent errors when a child component tries to access a store item that no longer exists?

Classic 'parent removes an item, child rendering that item crashes during the same render' bug. Fixes (best to worst): guard with conditional rendering in the parent (don't render the child if the item is gone); read the item by id in the child and bail to null if undefined; use a key that changes on removal so the child unmounts cleanly; move the read to a selector that returns undefined safely.

4 min
React
Medium
What is the role of React Router, and how does it work with dynamic routing?

React Router is the de-facto SPA routing library. It maps URLs to component trees, handles navigation without full page reloads, and provides hooks (`useNavigate`, `useParams`, `useLocation`) for programmatic access. Dynamic routing: `<Route path='/users/:id' element={<User/>} />` extracts `id` via `useParams()`. v6/7 adds nested routes, loaders (data fetching co-located with route), and form actions.

7 min
React
Medium
How would you implement protected routes and authentication in React?

Wrap protected routes in a guard component that reads auth state from a context/store and either renders the children, redirects to `/login` (with a `?next` param so post-login lands on the requested page), or renders a loading state during the auth probe. For role-based access, wrap a second guard around routes that require specific roles. The frontend guard is **UX**, not security — every protected API endpoint must enforce auth server-side independently.

8 min
React
Medium
How would you protect routes based on user roles, for example admin versus user?

Layered: server enforces (authoritative — API endpoints check role on every request); router-level guard component on the client checks role and redirects/denies; conditionally render UI elements (hide admin buttons for non-admins). Never trust the client — the client guard is UX only. Bake role into the auth token; refresh it when roles change.

5 min
React
Medium
How do you handle API calls and errors in a React application?

Use TanStack Query (or RTK Query / SWR) over hand-rolled `useEffect + fetch`. Handle the four states (idle, loading, success, error) explicitly. Distinguish error classes: network, 4xx (user / validation), 5xx (server), abort. Retry transient errors with backoff; don't retry 4xx. Show inline errors per query and a global error boundary for unexpected crashes. Cancel stale requests on dependency change. Always revalidate on the server.

9 min
React
Medium
How do you handle asynchronous code execution and state updates in React?

Run async in useEffect with AbortController for cancellation, or use React Query/SWR for caching, retries, and dedup. Inside event handlers, await freely but guard against unmounts. For state updates from async, use functional updaters to avoid stale closures. React 18 batches setState across promises automatically. For race conditions (rapid inputs), cancel previous in-flight requests or track a request id and discard outdated responses.

7 min
React
Easy
What are the different ways to intercept API requests in a React project?

Six common interception points: (1) axios interceptors for auth headers, retries, logging; (2) a wrapped fetch helper used app-wide; (3) React Query's onError/fetcher global hooks; (4) a Service Worker for network-level intercept (offline caching); (5) MSW for tests/dev mocking; (6) browser DevTools Network throttling/blocking for ad-hoc cases.

8 min
React
Medium
Does React use Promise.allSettled for parallel API calls, and how would that work internally?

No — React itself doesn't make API calls. The developer does, via fetch/axios/React Query. To parallelize, the developer uses Promise.all (fails fast) or Promise.allSettled (resolves to per-promise results regardless of failures). React Query handles parallelism via independent useQuery hooks that fire concurrently. Suspense + use() enables waterfall avoidance via parallel data dependencies.

7 min
React
Medium
How would you handle loading indicators or fallback UI during data fetching?

Model status as an enum (idle/loading/success/error/empty), not a boolean. Use skeleton screens over spinners for content, match the skeleton to the real layout to avoid shift, debounce indicators for fast loads, and use Suspense for code/data loading. Always handle empty and error too.

5 min
React
Medium
How would you manage filtered result state and its interaction with an API?

Decide where filtering lives: server-side for large data (filters become query params, debounced) or client-side for small data (memoized derive from a source list — don't store filtered results as separate state). Sync filters to the URL, handle loading/empty/error per filter change, and cancel stale requests.

5 min
React
Medium
What is the difference between optimistic and pessimistic UI updates?

Optimistic = update UI immediately, send the request, roll back on failure. Pessimistic = show a loading state, update only on success. Optimistic feels faster but needs rollback paths and clear error UX. Use optimistic for high-confidence, low-stakes mutations (likes, toggles, list reorders); pessimistic for irreversible or expensive ops (payments, deletions, bulk actions).

7 min
React
Medium
How do you use React's useOptimistic hook for instant UI updates?

`useOptimistic(state, reducer)` returns `[optimisticState, addOptimistic]`. Call `addOptimistic(action)` inside a transition (typically before `await api.submit()`); the UI shows the optimistic state immediately; once the underlying state updates (or the transition finishes), `optimisticState` reverts to derived-from-real. Rollback on error is automatic. Pairs with Server Actions in React 19.

4 min
React
Medium
How does the useActionState hook manage async actions and form state in React?

`useActionState` (React 19) wraps an async server/client action. It returns `[state, dispatch, isPending]` — `state` is the action's last return value, `dispatch` invokes the action (queues across calls), `isPending` reflects in-flight status. Designed for forms: `<form action={dispatch}>` works with progressive enhancement. Replaces a lot of useState + useTransition boilerplate.

3 min
React
Medium
In an e commerce product listing where multiple users add to cart, how would you use React Query or SWR with optimistic updates to prevent stale UI?

Optimistic update on click: instantly increment the cart count in the React Query cache, then fire the mutation. On error, rollback. Use `useMutation` with `onMutate` (snapshot + optimistic write), `onError` (restore snapshot), `onSettled` (invalidate to refetch source of truth). For multi-user race conditions, server returns the canonical state and we reconcile. Show a 'syncing' indicator if the mutation is in flight.

8 min
React
Medium
How do you handle real time updates in a React application efficiently?

WebSocket (or SSE for one-way) → push updates into a normalized React Query cache or Zustand store. Dedup by id. On reconnect, fetch missed events since last timestamp. Memoize selectors; virtualize the list view. Backoff + jitter on reconnect. Use AbortController to cancel stale fetches. Optimistic UI for sends; reconcile when server confirms.

5 min
React
Medium
What is lazy loading in React and how does it improve application performance?

Lazy loading defers downloading/executing a component until it's actually needed. `React.lazy(() => import('./Heavy'))` returns a component that fetches its chunk on first render, wrapped in `<Suspense fallback={...}>`. Improves initial bundle size, time to interactive, and LCP. Best for routes, heavy widgets (charts, editors), and modals. Pair with preload-on-intent (hover) to hide network latency.

6 min
React
Medium
How do you use React.lazy and Suspense to load components only when needed?

`React.lazy(() => import('./X'))` returns a component that resolves on first render via dynamic import — the bundler emits a separate chunk. Wrap it in `<Suspense fallback={<Spinner/>}>` to show UI while the chunk downloads. Best for route-level code splitting and heavy components (charts, editors, modals) that aren't on the critical path.

7 min
React
Medium
Why do React components re render?

A component re-renders when: (1) its state changes via setState, (2) its parent re-renders, (3) a context it consumes changes, (4) a hook it uses signals a change. Re-rendering is React's default — it does NOT mean a DOM update; React diffs the output and only commits actual changes. To skip a re-render, use React.memo with stable props, split contexts, or move state down.

6 min
React
Medium
What causes unnecessary re renders in React and how do you prevent them?

Common causes: parent re-render cascading, unstable prop references (new object/array/function each render), context value changing every render, hot state in Context, missing memoization for expensive children. Fixes: keep prop references stable (useMemo/useCallback when memo is downstream), split context, lift hot state to a selector-based store, React.memo for genuinely heavy children. Profile before applying.

4 min
React
Medium
How do unnecessary re renders happen in React and how do you avoid them?

Re-renders happen when state, props, or context changes. Unnecessary ones: parent re-renders cascade to children even when their props are identical; new object/array/function literals on every render bust React.memo; context value object recreated each render re-renders every consumer. Fix selectively: lift state down, split context, memoize stable references with useCallback/useMemo, use React.memo on expensive subtrees, profile before optimizing. Don't memoize everything — measure first.

8 min
React
Easy
How do you design React components for predictable re renders?

Predictable re-renders: colocate state so changes have a narrow blast radius; memoize children with React.memo + stable callback identity (useCallback/useMemo for props); split contexts so a frequently-changing slice doesn't re-render unrelated consumers; for hot state, use external stores (Zustand) with selector-based subscriptions; profile with DevTools to verify before optimizing.

5 min
React
Medium
How do you manage state in a complex app to avoid unnecessary re renders?

Classify state and place it well (server-cache lib for server state, colocate local state, selector stores for global), keep state low and narrow, split contexts, stabilize references, memoize selectively, and measure with the Profiler. Structure beats sprinkling memo everywhere.

7 min
React
Easy
What are the most common performance bottlenecks in React applications?

Big initial bundle, hydration cost, re-rendering large trees on every state change (no memo, context misuse), expensive renders (heavy list rendering without virtualization, recomputation per render), long synchronous work in handlers (INP), image-heavy LCP, unnecessary effects, memory leaks (no cleanup). Most are addressable with profiling + targeted memoization, virtualization, RSC, and transitions.

5 min
React
Medium
How do you distinguish between React side and browser side rendering bottlenecks?

React DevTools Profiler measures component render time and shows what re-rendered and why. Chrome Performance panel shows main-thread tasks including style, layout, paint, composite — browser work. If Profiler shows fast renders but the user sees jank, the browser's layout/paint is the culprit. If Profiler shows slow renders, optimize React (memo, lists, context). Pair the two tools.

4 min
React
Medium
How do you optimize a React application end to end?

Categories: initial load (code splitting, RSC, image pipeline, critical CSS), runtime renders (memo + stable refs, split context, virtualize, defer non-urgent updates), data layer (React Query for caching/dedup, optimistic UI), bundle hygiene (analyzer, tree shaking, dynamic imports), observability (web-vitals RUM, Sentry). Profile before optimizing. Structural fixes beat micro-memo.

5 min
React
Medium
How do you optimize React applications for performance?

Layered: (1) measure with Profiler + Lighthouse; (2) ship less JS — code split per route, lazy-load heavy components, prune deps; (3) render less — stable keys, React.memo on hot rows, useMemo/useCallback for stable identities, split contexts; (4) defer non-urgent work with startTransition / useDeferredValue; (5) virtualize long lists; (6) optimize images/fonts; (7) cache server state with React Query. Profile FIRST.

9 min
React
Medium
How do you debug performance issues in a React application?

Start with RUM (web-vitals: LCP, INP, CLS, p75 in prod). Reproduce in dev → React DevTools Profiler shows which components rendered, why, and how long. Chrome Performance panel for main-thread tasks. Lighthouse for asset/CSS issues. Memory panel for leaks. Bundle analyzer for size. Don't optimize without measurement.

5 min
React
Medium
How would you debug a performance bottleneck in a React app using DevTools?

1) Reproduce with throttling. 2) React DevTools Profiler — record interaction, look at flame graph (slow renders), 'Why did this render', highlight updates for visual fan-out. 3) Chrome Performance panel for main-thread/long-tasks/layout/paint. 4) Identify category: render fan-out, expensive single render, layout thrash, or non-React JS. 5) Targeted fix. 6) Measure delta. Always profile production builds for accurate numbers.

4 min
React
Medium
How would you reduce the initial page load time of a React application by forty percent?

Audit: bundle analyzer (heavy deps), Lighthouse (render-blocking, LCP image), web-vitals RUM. Fixes: replace heavy deps (moment → date-fns), code split per route + lazy modals/charts, RSC for non-interactive parts, AVIF/WebP + responsive srcset for LCP image, preconnect to CDN, critical CSS inline, self-host fonts, eliminate render-blocking JS. Each lever measured for delta.

5 min
React
Medium
How would you re render a React component when the window is resized?

Subscribe to the window resize event in a useEffect, store the dimension in state so a change triggers a re-render, and clean up the listener on unmount. Throttle/debounce the handler for performance. Extract it into a reusable useWindowSize hook; consider ResizeObserver for element-level sizing.

5 min
React
Medium
How do you detect a memory leak in a React or frontend application?

Chrome DevTools Memory tab: take a heap snapshot, navigate away from the suspect feature, force GC, take another snapshot. Compare. Filter by 'Detached HTMLElement' or by component class names. Performance Monitor shows growing heap or DOM node count over time. Common culprits: uncleaned event listeners, timers, subscriptions, refs holding unmounted DOM, closures capturing large state. StrictMode dev double-mount surfaces missing cleanups.

8 min
React
Medium
How do you handle memory leaks in React applications?

Pair every subscription with cleanup: `useEffect` returns a teardown; remove listeners; clear intervals; abort fetches with AbortController; unsubscribe from stores. Avoid holding refs to large objects in long-lived closures. Bound caches (LRU). Detect with DevTools Memory snapshots (detached DOM, retained size). Strict Mode helps surface missing cleanup in dev.

4 min
React
Medium
How would you debug and fix a memory leak in a React application?

1) Reproduce — repeatedly trigger the suspected leaky path. 2) DevTools Memory panel — take heap snapshot, repeat the leak path, take another, compare; look at retained size + 'Detached HTMLElement' rows. 3) Identify the retainer — usually a missing listener removal, interval not cleared, or closure over big data. 4) Fix with cleanup in useEffect return / AbortController / bounded cache. 5) Verify heap returns to baseline.

4 min
React
Medium
How does React handle re renders and memory management?

React re-renders by calling the component function again, building a new VDOM, diffing, and committing minimal DOM changes. Memory: each fiber persists across renders (state, refs, effect cleanups). Old VDOM nodes are discarded for GC. Memory leaks come from uncleaned subscriptions, timers, detached DOM references in refs, and closures that capture large objects. Effect cleanup is the primary defense.

7 min
React
Medium
How would you optimize React rendering performance for large lists, for example ten thousand rows?

Virtualize (TanStack Virtual / react-window) — render only visible rows. Memoize the row component. Stable keys. Avoid layout reads in row render. Defer non-urgent updates with `useDeferredValue` or `startTransition`. For variable heights use measurement cache. Server-side filter/sort for huge datasets so the client only handles a window. Don't memoize the list itself — focus on rows.

4 min
React
Medium
How would you optimize React performance when handling very large lists or grids?

Virtualize: render only the visible rows (react-window, TanStack Virtual). Memoize each row (React.memo) with stable callbacks (useCallback). Use stable ids for keys. Move filter/sort into useMemo or a Web Worker. Server pagination for very large data. For tables: sticky header outside scroll container, sticky columns via position sticky. Profile to verify 60fps scroll.

8 min
React
Medium
How would you optimize performance in a React app with large component trees?

Profile first. Then: split context so updates fan out narrowly, memoize expensive subtrees with stable prop refs, virtualize lists, lift hot state out of Context to a selector store, use `useDeferredValue` / `startTransition` for non-urgent updates, RSC for non-interactive parts, code split routes. Avoid the 'memoize everything' anti-pattern — most renders are cheap.

4 min
React
Medium
How would you optimize rendering of a React component that handles large datasets?

Layer fixes: (1) virtualize the rendered list (TanStack Virtual / react-window) so DOM stays constant; (2) paginate or cursor-fetch the data so memory stays bounded; (3) memoize row components + stable item props; (4) avoid re-creating object/function literals in JSX; (5) useTransition for filter/sort updates so input stays snappy; (6) move heavy compute (parsing, sorting) off the main thread with web workers. Measure with Profiler before each change.

9 min
React
Medium
How would you optimize a React application rendering one hundred thousand items in a list?

Don't render 100k items. Virtualize so only the visible ~30 are mounted (react-window, TanStack Virtual). Stable ids as keys. Memoize the row component. Move filter/sort into useMemo or a Web Worker. Paginate or chunk loading from the API. For tables: pin a header, scroll only the body. For search: index once, filter the index, not the full list.

8 min
React
Medium
hot
How would you implement infinite scrolling in React?

Use IntersectionObserver on a sentinel element to trigger the next page fetch. Track cursor + loading + hasMore in state, dedupe in-flight requests, and virtualize once rendered rows exceed a few thousand.

7 min
React
Easy
How would you implement an infinite scroll component in React with data fetching and error handling?

Combine TanStack Query's useInfiniteQuery (paginated fetching, cursors, dedup, retry) with IntersectionObserver on a sentinel near the list bottom. Show loading sentinel, handle error with retry button, handle empty + end-of-list. For massive datasets pair with virtualization (TanStack Virtual). Make sure cleanup observers on unmount, AbortController on stale fetches, and the IO doesn't double-fire when pages arrive.

9 min
React
Hard
How would you implement a virtualized list to render one hundred thousand rows efficiently?

Render only the slice of rows within the scroll viewport plus overscan. Maintain total scroll height via a spacer or absolutely-positioned container. For 100k rows, fixed heights are simplest; dynamic heights require measurement caches. Use `@tanstack/react-virtual` in production; for an interview, code it from scratch using a scroll listener + visible-range math.

8 min
React
Easy
What are the benefits of server side rendering in React applications?

SSR returns server-rendered HTML so the user sees content immediately — better FCP/LCP, better SEO, faster first paint on slow devices, link-preview support (Open Graph). Trade-offs: origin cost per request, hydration (a long task), TTFB depends on server work. Best fit: content-heavy or SEO-critical pages. Streaming SSR + RSC mitigate the costs.

5 min
React
Easy
What is hydration in server side rendering?

Hydration is the process where the client React runtime takes over server-rendered HTML: it walks the existing DOM, attaches event listeners, and reconciles state. Server sends HTML for fast first paint; client `hydrateRoot()` makes it interactive. Mismatches between server and client markup throw hydration errors. Modern variants: partial hydration, streaming SSR, React Server Components.

7 min
React
Medium
How do you handle SSR and hydration in complex React applications?

Hydration is the client running React to attach handlers to server HTML. In complex apps: prevent mismatches (same data, same time, same flags on server + client); code-split + lazy-hydrate heavy below-the-fold parts; use Suspense + streaming so hydration is incremental; use RSC to skip hydration for non-interactive UI; defer non-critical to `requestIdleCallback`. Mismatches usually mean impure render.

6 min
React
Medium
How does React's rendering process work under the hood?

Two phases: **render** (call components, build a fiber tree, diff against previous) and **commit** (apply DOM changes). Render is interruptible in concurrent mode; commit is synchronous. Each component instance is a Fiber node with state, hooks, and references. Reconciliation pairs elements by type + key; same type → update, different → unmount + mount.

5 min
React
Medium
How does React's reconciliation process update the DOM efficiently?

Reconciliation is React's algorithm for diffing two element trees and computing the minimum DOM mutations to transform the previous tree into the new one. Heuristics: (1) different element types remount the whole subtree; (2) same type diffs attributes/children; (3) keys identify list items across renders. O(n) where n = tree size, vs naive O(n³) for general tree diff. Fiber makes the walk interruptible.

7 min
React
Hard
What is React Fiber and how does it improve rendering performance?

Fiber is React 16's rewrite of the reconciler that splits rendering work into small units of work (fibers), each interruptible. The scheduler can pause a render, yield to the browser for high-priority work (input, animation), then resume — keeping the main thread responsive. Enables concurrent features (useTransition, Suspense, time-slicing). Pre-Fiber React (Stack reconciler) was synchronous and blocked the main thread on big trees.

7 min
React
Hard
hot
Can you explain React Fiber in depth?

Fiber is React's reconciler: a linked-list tree of work units that can be paused, resumed, and prioritized. It's what unlocked concurrent rendering, Suspense, and transitions.

10 min
React
Medium
What are the concurrent features introduced in React 18 and why do they matter?

React 18+ can render in the background, interrupt itself, and prioritize urgent updates. The primitives: `useTransition` / `startTransition` (mark non-urgent updates), `useDeferredValue` (lag a value to keep input responsive), Suspense for data + code streaming, and automatic batching across async boundaries. They don't make React faster — they let you schedule work so that user input always wins.

9 min
React
Medium
Can you explain the concurrent features introduced in React 18?

Concurrent rendering lets React pause/resume/abandon renders. Key features: automatic batching across async boundaries, `startTransition` / `useTransition` for non-urgent updates, `useDeferredValue` for lagging expensive derivations, Suspense for data + lazy components, streaming SSR with selective hydration. The model: urgent updates (input) preempt non-urgent (large list re-renders).

4 min
React
Hard
What are React Server Components and how do they change app architecture?

RSC are React components that run only on the server, render to a special serialized format streamed to the client, and never ship their code or dependencies to the browser. Mix with Client Components (`"use client"`) for interactivity. Benefits: zero JS for static parts, direct DB access, secrets stay server-side, automatic streaming. Trade-off: a new mental model — you can't pass functions or class instances across the boundary.

10 min
React
Easy
How would you build dark mode and theming support in a React app?

CSS custom properties for theme tokens, toggled via a data-attribute/class on <html>. Theme state in Context, persisted to localStorage, defaulting to prefers-color-scheme. Critical detail: apply the theme before first paint (inline script) to avoid a flash of the wrong theme (FOUC).

4 min
React
Medium
How would you implement dynamic theming with light and dark mode in a React app?

Use CSS custom properties for color tokens; toggle a `class="dark"` or `data-theme` attribute on `<html>` to flip them. Read user preference from localStorage, fall back to `prefers-color-scheme`. Set the class **before first paint** (inline script in `<head>` for SSR) to avoid a light→dark flash. Tailwind: `darkMode: "class"`. Persist and broadcast changes across tabs.

7 min
React
Hard
How would you design and implement a light and dark theme switcher in a scalable React app?

Tokens as CSS variables under `[data-theme]` or a class on `<html>`. Resolve theme on mount from localStorage or `prefers-color-scheme`. Apply before first paint via inline `<script>` to avoid flash. Provide a React context for components to read the current theme. Persist user choice. Respect `prefers-color-scheme: dark` as default. Support system / light / dark trichotomy.

4 min
React
Easy
How do you write clean, maintainable component logic in React?

Principles: one responsibility per component, separate UI from logic (custom hooks), props as the public API (small + named), state colocated where used, derive don't store, lift state only when necessary, names that describe purpose not implementation. Avoid prop drilling > 2 levels (compose, context, or store). Test by behavior, not implementation.

4 min
React
Easy
How would you build a reusable UI component in React?

Open-ended 'build a UI component' prompt. Approach: clarify the spec (what does it do, what props, what variants), sketch the API first, build the simplest working version, then layer accessibility, keyboard support, controlled/uncontrolled modes, and edge cases. Examples: dropdown, modal, tabs, tooltip. Lead with the API; the implementation follows.

8 min
React
Medium
How would you convert an existing piece of UI into a reusable component?

Identify what's variable (data, behavior, presentation) vs fixed (the pattern). Lift variable bits to props: typed data, callbacks for behavior, slot props or `children` / `renderItem` for presentation. Keep the API minimal — fewer props that compose well beat many flags. Style via tokens or `className` passthrough. Document with stories/examples.

4 min
React
Medium
What are the different approaches to styling React components and when do you use each?

Six approaches: (1) plain CSS / SASS files; (2) CSS Modules — scoped class names per file; (3) Tailwind / Atomic CSS — utility classes; (4) CSS-in-JS (styled-components, emotion) — JS-authored styles with dynamic props; (5) zero-runtime CSS-in-JS (vanilla-extract, Linaria, Panda); (6) framework-native (Next.js global + module CSS). Modern default: Tailwind or CSS Modules. Avoid runtime CSS-in-JS for hot paths.

7 min
React
Easy
How would you build a React list with collapse and expand functionality?

Common build. Store expanded state as a Set<id> for O(1) toggle. Each row reads its expanded state and renders children when open. For 'only one open at a time' use a single id. For animation, use height: auto with transform tricks or framer-motion's AnimatePresence. Avoid storing expanded state inside the row component if you need controlled state from the parent.

6 min
React
Easy
How would you implement a Tabs component in React?

Compound component pattern: <Tabs value, onValueChange><Tabs.List><Tabs.Trigger value /></Tabs.List><Tabs.Panel value /></Tabs>. Use Context to share active value between List and Panels without prop drilling. A11y: ARIA roles tablist/tab/tabpanel, aria-selected, aria-controls/labelledby, keyboard support (Left/Right/Home/End to navigate, Tab to enter panel). Support controlled + uncontrolled. For production, just use Radix or React Aria — they handle the dozen edge cases.

9 min
React
Medium
How would you build a notification system with queuing and auto dismiss behavior in React?

Toast manager: context/store of active toasts, a `<ToastContainer/>` portal that renders them stacked, imperative API (`toast.success(msg)`) backed by the store, per-toast options (variant, duration, dismissible, action), auto-dismiss timers, queueing if max-visible exceeded, swipe-to-dismiss, focus management, ARIA live region for accessibility.

5 min
React
Medium
How would you manage overlapping toasts using priority based queuing?

Central queue with a max visible cap, priorities (`error > warning > info > success`), and a dedupe key to merge repeat messages. Important toasts (errors) preempt; low-priority toasts wait. Each toast tracks its own timer; pause on hover; aria-live for screen readers. Use the Sonner / Radix Toast primitives instead of rolling your own.

4 min
React
Medium
How would you queue toasts so they do not all stack at once?

Keep two lists: visible (capped at N) and a queue. When a toast is dismissed, promote the next queued one. Track timers per visible toast. Optionally de-dupe and prioritize errors. The key is separating 'added' from 'shown'.

4 min
React
Medium
How would you implement undo and redo functionality in a React based drawing or form app?

Two viable models: (1) Snapshot stacks — store past/present/future state snapshots; on undo, pop past → present and push old present to future. Cheap with structurally-shared state (Immer). (2) Command pattern — store reversible operations (`apply`/`invert`). Better for huge state (drawings) where snapshots are expensive. Coalesce rapid changes (typing) into one history entry; cap history depth.

7 min
React
Medium
How would you build a To Do list in React and optimize it to avoid unnecessary re renders?

Classic interview build. Keys move from index → stable id. Split state by concern (input vs list). Memoize the row component with React.memo and pass stable callbacks via useCallback. Use functional updaters in setState to avoid stale closures. For very long lists, virtualize with react-window. Avoid putting all todos in a single object that gets re-cloned per keystroke.

6 min
React
Easy
How would you create a React app without using create react app?

Yes — CRA is deprecated. Modern starters use Vite (`npm create vite@latest`) or Next.js (`npx create-next-app`). For full control, install `react`, `react-dom`, a bundler (Vite/esbuild/Rspack), TypeScript, and an entry that calls `createRoot(...).render(<App/>)`. CRA is slow and unmaintained — there is no reason to start with it in 2025+.

6 min
React
Medium
How do you structure a scalable React application?

Feature-folder structure (group by feature, not by file type), clear layers (UI primitives → domain components → pages), absolute imports, shared utilities/types in lib, server state via React Query, route-level code splitting, error boundaries per route, ESLint + Prettier + TypeScript + tests, monorepo if multiple apps share code. Keep boundaries explicit: features import from lib, not from each other. Document deviations in README.

9 min
React
Medium
How does TypeScript enhance React development in practice?

Typed props/state catch bugs at compile time. Generics for reusable components (`<List<T>>`) and hooks (`useState<User>`). Discriminated unions for state machines (`{ status: 'loading' } | { status: 'success', data: T }`). Editor autocomplete for prop names and event types. Refactor-safe rename. API contract typing with Zod + inferred types. Best with strict mode on and exhaustive deps lint.

8 min
React
Medium
How do you run A/B tests in React applications?

Use a feature-flag/experiment SDK (GrowthBook, Statsig, LaunchDarkly, Optimizely, Vercel/Posthog flags). Initialize on app start with a stable user id, then read variant via a hook: `const variant = useExperiment('checkout-cta')`. Render conditionally. Track exposure + conversion to the same analytics pipeline. SSR needs the variant resolved on the server to avoid hydration flicker. Always have a kill switch.

8 min
React
Easy
What are common mistakes developers make in production React applications?

Top hits: server data in Redux (reinventing React Query); over-memoization; missing keys / unstable keys (causing remounts); huge bundle from named-namespace imports; CSR for content pages; missing error boundaries; useEffect dep arrays wrong (stale closures or missing deps); state too high in tree; not handling loading/error/empty states; no a11y; no error monitoring; no perf budget; lazy-loading the LCP image.

8 min
React
Easy
How would you implement a polyfill for the useState hook?

`useState(initial)` returns `[value, setter]`. Polyfill via the component's hook slot array: on first render, store initial; on subsequent renders, return whatever's in the slot. The setter schedules a re-render (with batching) and writes the new value into the slot.

4 min
React
Easy
How would you implement a polyfill for the useEffect hook?

`useEffect(fn, deps)` runs `fn` after commit if deps changed (or every commit if no deps); calls the previous cleanup before each re-run and on unmount. Polyfill: store `{ deps, cleanup }` in the hook slot; in a 'after-render' phase, compare deps; if changed, run cleanup then fn, save new cleanup.

5 min
React
Easy
How would you implement a polyfill for the useRef hook?

useRef returns a stable mutable object { current } that persists across renders and does NOT trigger a re-render when mutated. The polyfill: use useState's lazy initializer once to create and hold a single { current } object — the trick is reusing the SAME object every render.

4 min
React
Easy
How would you implement a polyfill for the useMemo hook?

`useMemo(factory, deps)` runs `factory()` on first render and again only when deps change (by `Object.is`); otherwise returns the cached value. Polyfill: store `{ value, deps }` in the component's hook slot array; on render, compare deps to previous; reuse or recompute.

4 min
React
Easy
How would you implement a polyfill for the useCallback hook?

`useCallback(fn, deps)` returns a stable function reference until `deps` change; equivalent to `useMemo(() => fn, deps)`. Polyfill via the same hook slot machinery: store [fn, prevDeps] across renders; if deps unchanged, return the previous fn; else store and return the new one.

4 min
React
Easy
How would you implement a polyfill for the useReducer hook?

useReducer can be built on useState: hold state in useState, and dispatch = a stable callback (useCallback/useRef) that calls setState(prev => reducer(prev, action)). Support the lazy init (third arg). The insight: useReducer is useState with the update logic centralized in a pure reducer.

4 min
React
Easy
How would you implement a polyfill for the useContext hook?

`useContext` reads the value from the nearest `<Context.Provider>` ancestor. Polyfill conceptually: each Context owns a stack of currently-rendering Provider values; useContext returns the top. In React's real implementation it's woven into fiber — but for an interview, a minimal store + Provider that pushes/pops via a render-tracking mechanism suffices.

4 min
React
Easy
How would you implement a polyfill for the useLayoutEffect hook?

useLayoutEffect runs synchronously after DOM mutations but before the browser paints — unlike useEffect which runs after paint. A 'polyfill' isn't a userland thing (it needs the commit phase); the real answer is explaining the timing and that on the server it must fall back to useEffect to avoid warnings.

4 min