React developer roles at Indian product companies and startups are among the most frequently hired positions in 2026, and the interview process has become standardised around a core set of hooks, state management, and performance topics. This guide covers what is asked at Indian product companies (Swiggy, Zepto, Razorpay, CRED, PhonePe, Meesho, Groww, Zerodha) and funded startups: core React concepts, hooks in depth, state management, performance optimisation, and coding questions at junior, mid, and senior levels.
Core React Concepts Tested in Indian Interviews
Virtual DOM and reconciliation: React's Fiber algorithm diffs the new and previous virtual DOM trees and applies the minimal set of changes to the real DOM. The key prop tells React which list items changed, moved, or were removed. Without stable keys, React re-renders unnecessarily and can produce incorrect state.
Controlled vs uncontrolled components: controlled components hold form values in React state (re-renders on every keystroke, input reflects state). Uncontrolled components store value in the DOM via a ref (faster for simple cases needing the value only on submission). Use controlled by default.
Component patterns: Higher-Order Components (HOC), Render Props, Compound Components (parent manages shared state via Context, children compose flexibly; Tabs with Tab and TabPanel children is the canonical example).
React Hooks in Depth
useState: functional update form (setCount(c => c + 1)) avoids the stale closure problem when updating based on previous state.
useEffect: dependency array controls when it runs ([] = mount only; [dep] = when dep changes; no array = every render). Cleanup function runs before the next effect and on unmount. Stale closure: an effect captures variable values from its closure at the time it ran; fix by adding the variable to the dependency array or using useRef.
useCallback: memoizes a function reference, preventing child re-renders when the function is passed as a prop. Without it, a new function object is created every render, breaking React.memo.
useMemo: memoizes a computed value. Do not overuse: memo, useMemo, and useCallback all have overhead; apply after profiling, not pre-emptively.
useRef: two uses: DOM access (pass as ref prop), and mutable values that persist across renders without triggering re-render (interval IDs, previous value tracking, latest callback version).
useContext: consumes Context without prop drilling. Every consumer re-renders when context value changes, even if the specific value it uses didn't change. Mitigate by splitting context or using a selector pattern with useMemo.
State Management: When to Use What
Decision tree: local state (useState) for state used by one component or its immediate children. Context for low-frequency updates (theme, auth state, language). NOT for high-frequency updates (form values, realtime data) because every consumer re-renders on every change.
Redux Toolkit (RTK): current best practice for Redux. createSlice combines action creators and reducers; createAsyncThunk handles async actions; RTK Query handles data fetching and caching. Use when: multiple components need the same data, you need Redux DevTools time-travel debugging, or state has complex update logic.
Zustand: minimal, no reducers, no boilerplate. Use when you want cross-component state with less complexity than Redux. Popular at Indian startups.
Jotai: atomic state (each piece is an 'atom'; components subscribe only to atoms they use). Fine-grained reactivity without a global Redux store.
Practise React developer interview questions with HireStepX's AI voice interviewer. Get scored feedback on your technical explanations and coding answers. First 2 sessions free.
Practice freeReact Performance Optimisation
React.memo: prevents re-render when props haven't changed (shallow equality). Only effective when props are stable references. Inline objects and functions created in the parent's render body get new references every render and break React.memo. Fix: useMemo for objects, useCallback for functions.
Code splitting: React.lazy(() => import('./Component')) + Suspense loads a component on demand, reducing initial bundle size. Critical for Indian mobile users on 4G.
Virtualised lists: react-window or react-virtual only renders items currently visible in the viewport. Essential for lists with hundreds or thousands of items.
React 18 concurrent features: useTransition marks a state update as non-urgent (keeps UI responsive while processing). useDeferredValue returns a deferred version of a value, deprioritising expensive re-renders triggered by user input.
React Coding Questions Asked in Indian Interviews
Q1: 'Fix this component: a counter supposed to increment every second but always shows 1.' Bug: stale closure in useEffect; setCount captures count = 0 at closure time. Fix: setCount(c => c + 1) (functional update) or add count to the dependency array.
Q2: 'Child uses React.memo but still re-renders on every parent render. Why?' Parent passes an inline function or inline object as a prop; new reference on every render breaks shallow equality. Fix: useCallback for functions, useMemo for objects.
Q3: 'Build a debounced search input that doesn't make an API call on every keystroke.' useState for input, useEffect with setTimeout (300ms debounce: clear timeout on every input change, fire search after timeout), useMemo or state for filtered results.
Q4: 'Build an infinite scroll list that loads more items when the user reaches the bottom.' IntersectionObserver on a sentinel element at the bottom of the list; when the sentinel enters the viewport, fetch the next page and append to state.
Frequently asked questions
Explore more