react + typescript interview questions from my last 11 rounds (and what they were actually testing)
6 companies, 11 rounds, bengaluru and remote. question types only, no NDA stuff.
Contents
day 22 of the hunt. 11 rounds at 6 companies so far: 4 machine coding, 3 DSA (easy to medium), 2 frontend system design, 2 behavioural. here's what came up in the frontend rounds, and what i think each question was really testing.
1. "why does this effect run twice?"
react 18 strict mode runs effects twice in development, on purpose, to catch effects that don't clean up after themselves. they are testing whether you know effects need cleanup. the wrong answer is "just remove StrictMode".
2. "fix this stale closure"
useEffect(() => {
const id = setInterval(() => {
setCount(count + 1); // count is always 0 here
}, 1000);
return () => clearInterval(id);
}, []);
the counter goes to 1 and stops. the interval callback closed over count from the first render. fix: setCount(c => c + 1). testing: closures and functional updates. this came up in 3 of 11 rounds.
3. "when would you use useMemo?"
an expensive calculation, or keeping a reference stable for a memoized child. testing whether you know it's not free and not a default. "i wrap everything in useMemo" is a red flag answer.
4. "type these props so a link needs href and a button needs onClick"
type ButtonProps =
| { variant: 'link'; href: string }
| { variant: 'button'; onClick: () => void };
function Action(props: ButtonProps) {
if (props.variant === 'link') {
return <a href={props.href}>Open</a>; // props.href is a string here
}
return <button onClick={props.onClick}>Go</button>;
}
testing: discriminated unions and narrowing.
5. "implement debounce, with types"
function debounce<T extends (...args: any[]) => void>(fn: T, ms: number) {
let t: ReturnType<typeof setTimeout> | undefined;
return (...args: Parameters<T>) => {
clearTimeout(t);
t = setTimeout(() => fn(...args), ms);
};
}
one interviewer asked why any[] and not unknown[]. answer: with strict function types, a function taking (q: string) is not assignable to one taking unknown, so the constraint has to be loose. they just wanted to see if i knew why.
6. "a search box filters 2,000 items and typing feels laggy. what do you do?"
stable keys, memoized rows, virtualize the list, and useDeferredValue or useTransition so typing stays responsive while the list catches up. testing: do you know where the time goes.
7. "what does this print?"
console.log('a');
setTimeout(() => console.log('b'), 0);
Promise.resolve().then(() => console.log('c'));
console.log('d');
// a, d, c, b
microtasks (promises) run before the next macrotask (setTimeout). testing: the event loop. came up twice.
8. "make this clickable div accessible"
use a button. that's it. that's the answer. if you must keep the div: role, tabIndex, and handlers for Enter and Space. but use a button.
9. the machine coding round: autocomplete in 60 minutes
debounced input, cancel the previous request with AbortController, keyboard navigation (up, down, enter, escape), and loading, empty and error states. what they're testing is completeness under time pressure. people build a beautiful dropdown and forget the error state. i did, once.
if you're interviewing for frontend in bengaluru right now, ask me anything in the comments. i've seen it all this month.
Written by
Sneha Kulkarni
Laid off in August from a quick commerce unicorn (along with 600 others). 6 yrs frontend, React/TS. Open to work, open to advice, not open to "everything happens for a reason". Bengaluru.
Get the best of #interview_horror weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to comment