Skip to content

Groww React JS Interview Questions & Answers

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

  1. Online assessment or assignment
  2. Technical round (coding or SQL)
  3. Design or problem solving round
  4. 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?

Save to ▾
Show answer
Define a type or interface and annotate the destructured props. type ProductCardProps = { title: string; price: number; tags?: string[]; onAdd: (id: string) => void; children?: React.ReactNode; }; function ProductCard({ title, price, tags = [], onAdd, children }: ProductCardProps) { return <div onClick={() => onAdd(title)}>{title} - Rs {price}{children}</div>; }
02

Which queries should you prefer in React Testing Library and why?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.

Save to ▾
Show answer
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.
05

How do you test a custom hook?

Save to ▾
Show answer
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.
06

What is Zustand and how do you use it?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.
08

Why is user-event preferred over fireEvent?

Save to ▾
Show answer
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.

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.
11

Create a Redux Toolkit slice for a counter.

Save to ▾
Show answer
createSlice generates action creators and the reducer. Immer lets you write mutating syntax safely. import { createSlice } from '@reduxjs/toolkit'; const counterSlice = createSlice({ name: 'counter', initialState: { value: 0 }, reducers: { increment: state => { state.value += 1; }, addBy: (state, action) => { state.value += action.payload; } } }); export const { increment, addBy } = counterSlice.actions; export default counterSlice.reducer;
12

When would you use useLayoutEffect instead of useEffect?

Save to ▾
Show answer
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.
13

Write a useDebounce custom hook.

Save to ▾
Show answer
Debouncing delays a value until the user stops typing, which reduces API calls. function useDebounce(value, delay = 400) { const [debounced, setDebounced] = useState(value); useEffect(() => { const t = setTimeout(() => setDebounced(value), delay); return () => clearTimeout(t); }, [value, delay]); return debounced; } const q = useDebounce(searchText); // fetch when q changes
14

What is tree shaking?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.
20

How do you find what is making a React page slow?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.
24

Why is React Hook Form popular?

Save to ▾
Show answer
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.
25

Show how to fetch data with TanStack Query.

Save to ▾
Show answer
TanStack Query caches by query key and handles loading, errors, retries and background refetching. const queryClient = new QueryClient(); // wrap app: <QueryClientProvider client={queryClient}> function Orders({ userId }) { const { data, isPending, error } = useQuery({ queryKey: ['orders', userId], queryFn: () => fetch(`/api/users/${userId}/orders`).then(r => r.json()), staleTime: 60_000 }); if (isPending) return <Spinner />; if (error) return <p>Error</p>; return <OrderList orders={data} />; }
26

How do you test a component that fetches data from an API?

Save to ▾
Show answer
Mock the network, not fetch itself, using Mock Service Worker (MSW), then wait for the UI. const server = setupServer( http.get('/api/users', () => HttpResponse.json([{ id: 1, name: 'Asha' }])) ); beforeAll(() => server.listen()); afterEach(() => server.resetHandlers()); afterAll(() => server.close()); test('shows users', async () => { render(<Users />); expect(await screen.findByText('Asha')).toBeInTheDocument(); });
27

A teammate writes setCount(count + 1) three times in a click handler and is surprised that the count increases by only one. Explain why.

Save to ▾
Show answer
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.
28

How do you create an error boundary in React?

Save to ▾
Show answer
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?

Save to ▾
Show answer
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.
30

How do you upload a file with a preview in React?

Save to ▾
Show answer
Use a file input, create a preview URL and send FormData. function AvatarUpload() { const [file, setFile] = useState(null); const preview = useMemo(() => file && URL.createObjectURL(file), [file]); useEffect(() => () => preview && URL.revokeObjectURL(preview), [preview]); async function upload() { const fd = new FormData(); fd.append('avatar', file); await fetch('/api/avatar', { method: 'POST', body: fd }); } return (<> <input type="file" accept="image/*" onChange={e => setFile(e.target.files[0])} /> {preview && <img src={preview} alt="preview" />} <button onClick={upload}>Upload</button> </>); }

Tips to crack the Groww React JS interview

  • 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.

React JS questions for similar companies