Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About Groww hiring for React JS roles
Groww is an Indian investment platform offering stocks, mutual funds, futures and options, fixed deposits and other financial products. Its engineering and analytics teams work on trading systems, user experience, risk and growth. It hires for software engineers, SDETs, data analysts and data scientists. Many users are first-time retail investors.
For React JS roles, this Groww practice set focuses most on Testing and Debugging (7), Props and State (5), State Management (4), React Fundamentals (4). It has 3 easy, 25 medium, 2 hard questions, so you can start easy and work up to the harder ones.
Company type
Fintech
Headquarters
Bengaluru, India
Main India offices
Bengaluru
Groww React JS interview process
Online assessment or assignment
Technical round (coding or SQL)
Design or problem solving round
Hiring manager round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for GrowwStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
How do you type props for a component in TypeScript?
Prefer queries accessible to everyone: getByRole (with the name option) first, then getByLabelText for form fields, getByPlaceholderText, getByText and getByDisplayValue. Use getByAltText and getByTitle for images and titles. getByTestId is a last resort when nothing else works. Role-based queries also check accessibility, because if a button cannot be found by role and name, screen reader users will struggle too.
03
How do you give default values to props in a function component?
Use JavaScript default parameters while destructuring props. defaultProps for function components was removed in React 19, so this is the standard way.
function Button({ label = 'Submit', variant = 'primary', onClick }) {
return (
<button className={`btn btn-${variant}`} onClick={onClick}>
{label}
</button>
);
}
04
Tell me about a time you had to learn a new tool or library quickly.
Situation: our project needed to switch from Jest to Vitest with a week's notice. Task: migrate around 300 tests. Action: I read the official migration guide, migrated one folder first to discover patterns, wrote a codemod for jest.fn to vi.fn replacements and documented gotchas for the team. Result: we finished in four days, test runs became much faster, and the guide helped others with later work.
Use renderHook from React Testing Library and wrap state changes in act.
import { renderHook, act } from '@testing-library/react';
import { useCounter } from './useCounter';
test('increments', () => {
const { result } = renderHook(() => useCounter(5));
act(() => result.current.increment());
expect(result.current.count).toBe(6);
});
If the hook needs context, pass a wrapper option with the provider.
Zustand is a small state library with a hook-based API and no Provider.
import { create } from 'zustand';
const useCart = create(set => ({
items: [],
add: item => set(s => ({ items: [...s.items, item] })),
clear: () => set({ items: [] })
}));
const count = useCart(s => s.items.length);
Components subscribe with selectors, so they re-render only when the selected slice changes.
07
A junior notices that every child component re-renders when the parent's state changes, even when their props did not change. How do you explain this?
By default, when a component renders, React re-renders all of its children, because it cannot know whether they depend on something else. Re-rendering is usually cheap since only real changes reach the DOM. If a child is expensive, wrap it in React.memo and keep its props stable with useCallback or useMemo, or let the React Compiler memoise automatically. Moving state down also helps.
fireEvent dispatches a single DOM event, such as one change event. user-event simulates full user interactions: typing fires keydown, keypress, input and keyup for every character, clicking includes pointer and focus events, and it respects disabled elements and visibility. This finds bugs that fireEvent misses. In current versions, call userEvent.setup() and await each interaction because they are asynchronous.
09
Show a Server Function used to handle a form in Next.js.
A function marked 'use server' runs on the server and can be passed to a form action.
// app/actions.ts
'use server';
import { revalidatePath } from 'next/cache';
export async function addTodo(formData: FormData) {
const title = String(formData.get('title'));
await db.todo.create({ data: { title } });
revalidatePath('/todos');
}
// app/todos/page.tsx
<form action={addTodo}>
<input name="title" required />
<button>Add</button>
</form>
Always validate input and check authorisation inside the function.
10
Your team has hundreds of snapshot tests that developers update blindly whenever they fail. What are the drawbacks of snapshot tests and what would you suggest?
A snapshot test saves the rendered output to a file and fails when future output differs. It is quick to write and catches unexpected changes. Drawbacks: large snapshots are hard to review, developers often blindly update them, and they fail on harmless markup changes while saying nothing about behaviour. Use small, focused inline snapshots for stable output, and prefer behaviour assertions for most component tests.
useEffect runs after the browser paints, which is fine for most side effects. useLayoutEffect runs synchronously after DOM changes but before paint, so it is used when you must measure layout and update immediately, for example positioning a tooltip based on its size, to avoid a visible flicker. It blocks painting, so overusing it hurts performance, and it does not run during server rendering.
Tree shaking is dead code elimination done by bundlers like Rollup (used by Vite), esbuild and webpack. They analyse ES module import and export statements and drop exports that are never used. It works only with static ESM syntax, not CommonJS require, and can be blocked by modules with side effects. Importing import { debounce } from 'lodash-es' instead of the whole lodash library keeps the bundle small.
15
In development your API call inside useEffect fires twice, but only once in production. Why does this happen, and what does StrictMode do?
StrictMode is a development-only wrapper that helps find bugs. It renders components twice to catch impure rendering, and mounts, unmounts and remounts components to check that effects clean up properly. This is why a fetch in useEffect may appear to fire twice locally. It does not happen in production. The fix is to write proper cleanup, not to remove StrictMode.
16
A cart page keeps the selected item object in state and also the items array. After editing the item's quantity, the details panel shows the old quantity. Why?
The selected item is a copy duplicated from the array, so updating the array does not update the copy. This breaks the single source of truth. Store only selectedId in state and derive the item during render: const selected = items.find(i => i.id === selectedId). Now there is one place where each item lives, and every view stays in sync automatically.
17
What is the difference between getBy, queryBy and findBy queries?
getBy returns the element or throws immediately if it is missing, so use it when the element should exist. queryBy returns null instead of throwing, which is the right choice to assert something is not present: expect(screen.queryByText('Error')).not.toBeInTheDocument(). findBy returns a promise and retries until the element appears or times out, used for content that appears after async work. Each has an AllBy variant for multiple elements.
18
Your team uses the array index as key in a todo list and users report that checkboxes get ticked on the wrong item after deleting a row. What is happening?
When an item is deleted, every later item shifts to a new index, so React matches old state and DOM nodes to the wrong items. Uncontrolled inputs and component state stay attached to the index, not the data. The fix is to use a stable unique id from the data as the key. Index keys are only safe for static lists that never reorder, filter or delete.
19
During a security review you find a payment provider's secret key in the browser's JavaScript bundle. What do you do?
Treat it as leaked: rotate the key immediately in the provider dashboard and check logs for misuse. Then fix the cause, usually the secret was in a public env variable such as NEXT_PUBLIC_ or VITE_, or imported into a client component. Move the call to a server route or Server Function that uses a server-only variable, add the server-only package to guard imports, and add secret scanning in CI.
Use the React DevTools Profiler: record an interaction, then check the flame chart for components with long render times and the reason each one re-rendered (enable 'record why each component rendered'). Pair it with the Chrome Performance panel for long tasks, layout and network. Enable highlight updates to spot unnecessary renders. Measure first, fix the biggest cost, then measure again in a production build.
21
A blog feature must render HTML content that comes from a CMS. Why is dangerouslySetInnerHTML risky and how do you use it safely?
React escapes values in JSX by default, which protects against XSS. dangerouslySetInnerHTML bypasses this and inserts raw HTML, so if the content comes from users or an untrusted CMS, attackers can inject scripts. If you must render HTML, sanitise it first with a library like DOMPurify, restrict allowed tags, and add a Content Security Policy. Also never put user input into href attributes without validating the protocol.
22
What is the difference between functional components and class components?
Class components extend React.Component, use this.state and lifecycle methods like componentDidMount. Functional components are plain functions that return JSX and use hooks such as useState and useEffect for state and side effects. Modern React code is written almost entirely with functional components because they are shorter, easier to test and reuse logic through custom hooks. Class components are still needed only for error boundaries.
23
Typing in a search box feels laggy because a big product list is filtered on every keystroke. How do you fix it?
Keep the input state urgent and make the expensive part deferred. Use const deferredQuery = useDeferredValue(query) and filter with deferredQuery inside useMemo, and wrap the list in React.memo. The input updates instantly while React renders the list in the background and can interrupt it. If filtering is still heavy, debounce it, move it to a Web Worker or filter on the server.
React Hook Form registers inputs as uncontrolled by default and reads values through refs, so typing does not re-render the whole form. This makes large forms fast. It provides validation, error messages, field arrays for dynamic rows, and integrates with Zod or Yup through resolvers. It has a small bundle and works with UI libraries through a Controller component for custom controlled inputs.
Inside one render, count is a constant snapshot, say 0. Each call schedules setCount(0 + 1), so all three set the same value 1, and React batches them into one render. State does not change immediately after calling the setter. To increment three times, use the updater form setCount(c => c + 1), which queues functions that each receive the latest pending value.
An error boundary catches errors thrown while rendering its children and shows a fallback UI. It must be a class component (or use the react-error-boundary package).
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error, info) {
logError(error, info.componentStack);
}
render() {
return this.state.hasError ? <p>Something went wrong</p> : this.props.children;
}
}
It does not catch errors in event handlers or async code.
29
What is the main performance pitfall of React Context and how do you avoid it?
Every component that reads a context re-renders when the provider value changes. If you pass a new object like value={{ user, setUser }} on each render, all consumers re-render even if nothing changed. Memoise the value with useMemo, split one big context into smaller ones (for example state and dispatch separately), and keep fast-changing data in a dedicated store like Zustand that supports selectors.
Learn stock market basics like orders, settlement, mutual fund NAV and SEBI regulations for domain discussion.
Practise test scenarios for order placement, market hours and payment failures for QA roles.
Prepare analytics cases on first-time investor activation and retention, which are central to Groww's growth.
Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
Practise the hard questions on this page aloud; Groww interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the Groww React JS interview?
Candidates usually go through 4 stages: Online assessment or assignment; Technical round (coding or SQL); Design or problem solving round; Hiring manager round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.
Which topics should I prepare for the Groww React JS interview?
This practice set leans on Testing and Debugging (7), Props and State (5), State Management (4), React Fundamentals (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Groww interviewers ask you to walk through real work.
Are these the exact questions asked at Groww?
No. These are curated practice questions that match the skills and difficulty usually tested in fintech interviews like Groww's. They are not a leaked or verified list of past questions.
Where does Groww hire React JS professionals in India?
Groww has large teams in Bengaluru. Openings and locations change often, so check the Groww careers page and filter by city and experience.