React Scenario-Based MCQ
Scenario-based multiple choice questions covering React, React 19, Redux, and Jest topics.
Table of Contents
L1: Fundamental (Entry-Level / Junior)
Focus: JSX, component basics, props, and rendering concepts.
- React Fundamentals: JSX, components, props, keys, and core rendering behavior.
- Component Lifecycle: Mounting, updating, cleanup,
useLayoutEffect, andshouldComponentUpdateequivalent.
L2: Intermediate (Junior-Mid / Developer)
Focus: Hooks, state handling, and form patterns.
- React Hooks: useState, useEffect, useRef, useCallback, useMemo, useReducer, and custom hooks.
- Forms & Controlled Components: Controlled inputs, uncontrolled components, multiple-input state, select elements, and React Hook Form.
- Context API: Sharing state without prop drilling and avoiding unnecessary re-renders.
L3: Advanced (Mid-Senior / Lead)
Focus: Performance, resilience, and code splitting.
- Performance Optimization: Memoization, debouncing, useTransition, and useDeferredValue.
- Error Boundaries: Catching render errors, fallback UIs, and promise rejection handling.
- Code Splitting & Lazy Loading: React.lazy, Suspense, and dynamic imports.
L4: Expert (Senior / Architect)
Focus: State management libraries, React 19, and testing.
- Redux & State Management: Reducers, middleware, useSelector, and combineReducers.
- Redux Toolkit: createSlice, createAsyncThunk, RTK Query, and createSelector.
- React 19 Features: use(), useFormStatus, useOptimistic, Server Actions, and ref as prop.
- Jest Unit Testing: Mocks, snapshots, async testing, and lifecycle hooks.
- React Testing Library: Queries, userEvent, findBy, and Redux-connected component testing.
L5: Framework & Ecosystem (Senior / Lead)
Focus: Next.js, routing, and ecosystem integrations.
- Next.js: SSG, SSR, ISR, App Router, layouts, Server Components, and middleware.
- React Router: v6 routing, nested routes, useParams, useNavigate, and protected routes.
- Miscellaneous: RxJS integration, StrictMode, Fragment, and key-based state reset.
# 1. React Fundamentals
Q. While looping over an array of numbers with no unique value, React warns for the unique key. What should be used to remove this warning?
- Use Index as the key
-
Use Math.random().toString() as the key
- A) a
- B) b
- C) Both a and b are correct
- D) Both a and b are incorrect
Answer & Explanation
**Answer: C) Both a and b are correct** **Explanation:** Both options remove the React unique key warning — React only requires a key prop to be present. Using the array **index** as a key is acceptable for static, non-reordered lists. Using `Math.random()` also removes the warning by supplying a key, but it is an anti-pattern: it generates a new key on every render, causing React to unmount and remount every list item, destroying component state and hurting performance. The question asks what *removes the warning*, not what is best practice — so both are technically correct.Q. Alex is working on a project where she needs to implement a new feature requiring dynamic component loading. She plans to use React CLI for setting up the project and ensuring the feature integrates seamlessly. Considering her goal to optimize component handling and building times, which React CLI feature should Alex use to improve performance and manage components effectively?
- A) Use the react-scripts to run and build components
- B) Utilize create-react-app for efficient component management
- C) Leverage custom React CLI script for specific component needs
- D) Implement React CLI commands for module bundling and optimization.
Answer & Explanation
**Answer: D) Implement React CLI commands for module bundling and optimization** **Explanation:** For dynamic component loading, module bundling and optimization (such as code splitting and lazy loading via `React.lazy`) is the right approach. These techniques allow components to be loaded on demand, reducing initial bundle size and improving build and runtime performance.Q. What will be the possible output for the below program?
export function App() {
const data = {
1: {
id: 1,
title: "test"
},
2: {
id: 2,
title: "qwerty"
},
3: {
id: 3,
title: "asdf"
},
}
return data
}
- A) It will return an error.
- B) It will return an undefined value.
- C) It will return the values in data.
- D) It will return a null value.
Answer & Explanation
**Answer: A) It will return an error.** **Explanation:** React components must return JSX (or `null`), not plain JavaScript objects. Returning a plain object causes a runtime error: *"Objects are not valid as a React child."* To render the data, you would need to map it into JSX elements.Q. Which JSX will return by following the App Component?
function App() {
return (
<div>Hello</div>
<div>World!</div>
);
}
- A) Hello World!
- B) World! Hello
- C) Nothing will return
- D) Error
Answer & Explanation
**Answer: D) Error** **Explanation:** A React component can only return a single root element. Returning two adjacent `` elements without a wrapper causes a compile-time error: *"Adjacent JSX elements must be wrapped in an enclosing tag."* The fix is to wrap them in a fragment `<>...</>` or a container element.
</details>
## Q. Suppose you are working on an e-commerce website. You must create a production package. Which command will you use?
- A) npm start
- B) npm run dev
- C) npm run prod
- D) npm run build
## Q. A developer writes the following component. What will be rendered in the browser?
```jsx
function Greet({ name }) {
return
```
- A) Hello, undefined!
- B) Hello, !
- C) Hello, World!
- D) A runtime error is thrown
## Q. A developer renders a list without a `key` prop. What is the primary risk?
```jsx
const items = ["Apple", "Banana", "Cherry"];
items.map(item => {item} );
```
- A) The browser will throw a SyntaxError
- B) React will silently skip items during updates
- C) React cannot efficiently reconcile list items and may produce incorrect UI on re-renders
- D) Keys are only needed for nested lists
## Q. A developer sees stale data after a state update. What is wrong with the following code?
```jsx
const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
setCount(count + 1);
}
```
- A) `useState` does not allow two updates in one function
- B) Both calls read the same `count` snapshot, so `count` only increases by 1
- C) The second `setCount` resets the state to 0
- D) This pattern throws a React error
## Q. A developer passes a new object literal as a prop on every render. What is the consequence?
```jsx
<UserCard style= />
```
- A) No consequence - React compares object values
- B) React skips rendering because the reference is the same
- C) `UserCard` will always re-render even if wrapped in `React.memo`, because the object reference changes
- D) Passing objects as props is not allowed in React
## Q. What does the following JSX compile to?
```jsx
const el = <button className="btn" onClick={handleClick}>Submit</button>;
```
- A) `document.createElement("button")`
- B) `React.createElement("button", { className: "btn", onClick: handleClick }, "Submit")`
- C) `React.createComponent("button", ...)`
- D) HTML string interpolation
## Q. A developer wraps several components with `withAuth(Component)` to enforce authentication. What React pattern does `withAuth` represent?
- A) Render Props
- B) Compound Components
- C) Higher-Order Component (HOC)
- D) Observer Pattern
## Q. A developer needs to render a modal dialog outside the parent DOM node to avoid `overflow: hidden` and z-index stacking issues. Which React API solves this?
- A) `React.createContext`
- B) `React.createPortal`
- C) `React.lazy`
- D) `React.forwardRef`
## Q. A developer has a component with no state, receiving only primitive props. Which optimization avoids re-rendering it when its parent re-renders with the same props?
- A) Wrap it in `React.lazy()`
- B) Extend `React.PureComponent` (class) or wrap with `React.memo` (function)
- C) Move all logic into `useEffect`
- D) Use `ReactDOM.createPortal`
## # 2. React Hooks
## Q. Suppose you are working on the use registration screen. You must call an input blur event from any other press event. Which React hook will you use? - A) useMemo - B) useReducer - C) useContext - D) useRef
## Q. You are working on a food delivery web application. On the restaurant selection, you want to get elements from its stable unique ID. Which React hook will you use?
- A) useRef
- B) useState
- C) useId
- D) useContext
## Q. A developer wants to run a side effect only when `userId` changes. Which implementation is correct?
```jsx
// Option A
useEffect(() => { fetchUser(userId); });
// Option B
useEffect(() => { fetchUser(userId); }, []);
// Option C
useEffect(() => { fetchUser(userId); }, [userId]);
// Option D
useEffect(() => { fetchUser(userId); }, [userId, fetchUser]);
```
- A) Option A - runs on every render
- B) Option B - runs once on mount
- C) Option C - runs whenever `userId` changes
- D) Option D - same as C but also re-runs if `fetchUser` reference changes
## Q. A developer wraps an event handler with `useCallback` but still sees child re-renders. What is the likely cause?
```jsx
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
```
- A) `useCallback` never prevents re-renders
- B) `count` is in the dependency array, so `handleClick` is recreated every time `count` changes, causing the child to re-render
- C) The child component must also use `useCallback`
- D) `useCallback` requires a second argument of `true`
## Q. What does `useMemo` return?
```jsx
const sortedList = useMemo(() => {
return [...items].sort((a, b) => a.localeCompare(b));
}, [items]);
```
- A) A memoized function
- B) A memoized value - the sorted array, recomputed only when `items` changes
- C) A ref to the previous render\'s sorted array
- D) A state setter for the sorted list
## Q. A developer uses `useRef` to hold a mutable value. What is true about this pattern?
```jsx
const timerRef = useRef(null);
function start() {
timerRef.current = setInterval(() => tick(), 1000);
}
```
- A) Changing `timerRef.current` triggers a re-render
- B) `timerRef.current` is reset to `null` on every render
- C) Mutating `timerRef.current` does not cause a re-render and persists across renders
- D) `useRef` can only hold DOM element references
## Q. A developer uses the `useReducer` hook. When should it be preferred over `useState`?
```jsx
const [state, dispatch] = useReducer(reducer, initialState);
```
- A) When the state is a single boolean
- B) When multiple sub-values depend on each other or next state depends on previous state in complex ways
- C) Only when integrating with Redux
- D) `useReducer` is deprecated in React 18+
## Q. What makes `useWindowWidth` a valid custom hook?
```js
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handler = () => setWidth(window.innerWidth);
window.addEventListener("resize", handler);
return () => window.removeEventListener("resize", handler);
}, []);
return width;
}
```
- A) The function accesses a browser API (`window`)
- B) The function name starts with `use` and calls built-in React hooks internally, following the Rules of Hooks
- C) The function returns exactly one value
- D) The function must be exported from a dedicated file
## Q. A developer violates the Rules of Hooks. What is wrong with the following code?
```jsx
function UserProfile({ isAdmin }) {
if (isAdmin) {
const [role, setRole] = useState("admin");
}
return ;
}
```
- A) `useState` cannot be used in functional components
- B) Hooks must not be called conditionally — the order of hook calls must be identical on every render
- C) The `if` block should be replaced with `useEffect`
- D) `isAdmin` must be listed in a dependency array
## Q. A developer calls `useContext(ThemeContext)` inside a component. When does the component re-render?
- A) Every time any state changes anywhere in the application
- B) Only when the component\'s own state changes
- C) Whenever the `value` prop of the nearest `ThemeContext.Provider` above it changes
- D) `useContext` never causes a re-render
## # 3. Component Lifecycle
## Q. What does the cleanup function returned from `useEffect` do? ```jsx useEffect(() => { const sub = subscribe(userId); return () => sub.unsubscribe(); }, [userId]); ``` - A) It runs before the component mounts for the first time - B) It runs after every re-render before the next effect executes, and on unmount - C) It runs only when the component unmounts - D) It cancels the `subscribe` call before it resolves
## Q. A class component uses `componentDidUpdate`. What is its hooks-based equivalent?
```jsx
componentDidUpdate(prevProps) {
if (prevProps.id !== this.props.id) {
fetchData(this.props.id);
}
}
```
- A) `useEffect(() => { fetchData(id); }, [])`
- B) `useEffect(() => { fetchData(id); }, [id])`
- C) `useLayoutEffect(() => { fetchData(id); })`
- D) `useMemo(() => fetchData(id), [id])`
## Q. A developer notices a layout flash when reading a DOM node\'s size. Which hook should replace `useEffect`?
- A) `useRef`
- B) `useMemo`
- C) `useLayoutEffect`
- D) `useTransition`
## Q. What is the `useEffect` equivalent of `componentDidMount` in a class component?
```jsx
// Class component
componentDidMount() {
fetchInitialData();
}
// Functional component — which option is the equivalent?
// Option A
useEffect(() => { fetchInitialData(); });
// Option B
useEffect(() => { fetchInitialData(); }, []);
// Option C
useEffect(() => { fetchInitialData(); }, [fetchInitialData]);
```
- A) Option A — runs after every render
- B) Option B — runs once after the initial render only
- C) Option C — runs after mount and when `fetchInitialData` changes
- D) There is no hooks equivalent of `componentDidMount`
## Q. A developer fetches data inside `useEffect` and updates state, but gets a warning: *"Can\'t perform a React state update on an unmounted component."* What is the correct fix?
```jsx
useEffect(() => {
fetchUser(userId).then(user => setUser(user));
}, [userId]);
```
- A) Move the `fetch` call outside the component
- B) Use a cleanup function with an `isMounted` flag or `AbortController` to cancel the update after unmount
- C) Wrap `setUser` in a `try/catch` block
- D) Replace `useEffect` with `useLayoutEffect`
## Q. A class component uses `shouldComponentUpdate` to skip re-renders. What is the functional component equivalent?
```jsx
// Class component
shouldComponentUpdate(nextProps) {
return nextProps.value !== this.props.value;
}
```
- A) `useEffect` with a comparison inside
- B) `React.memo` with a custom comparator function as the second argument
- C) `useMemo` wrapping the entire JSX return
- D) `useCallback` on the render function
## # 4. React 19 Features
## Q. React 19 introduces the `use()` hook. What does the following code do? ```jsx import { use } from "react"; function UserProfile({ userPromise }) { const user = use(userPromise); return
## Q. A developer uses the React 19 `useFormStatus` hook. What data does it expose?
```jsx
import { useFormStatus } from "react-dom";
function SubmitButton() {
const { pending } = useFormStatus();
return <button disabled={pending}>Submit</button>;
}
```
- A) Validation errors for the parent form fields
- B) The submission state of the nearest parent `
Answer & Explanation
**Answer: D) npm run build** **Explanation:** `npm run build` triggers the production build script (e.g., via Create React App or Vite), which bundles and minifies the application for deployment. `npm start` runs the development server, `npm run dev` is a common dev-server alias, and `npm run prod` is not a standard script.Hello, {name || "World"}!
; }Answer & Explanation
**Answer: C) Hello, World!** **Explanation:** When `name` prop is not provided it is `undefined`, which is falsy. The `||` operator falls back to `"World"`, so the output is `Hello, World!`.Answer & Explanation
**Answer: C) React cannot efficiently reconcile list items and may produce incorrect UI on re-renders** **Explanation:** React uses `key` to identify which items changed, were added, or removed. Without keys, React falls back to index-based diffing, which can cause incorrect state association and performance issues.Answer & Explanation
**Answer: B) Both calls read the same `count` snapshot, so `count` only increases by 1** **Explanation:** State updates in React are batched. Both calls close over the same `count` value. Use the functional updater `setCount(prev => prev + 1)` to guarantee sequential increments.Answer & Explanation
**Answer: C) `UserCard` will always re-render even if wrapped in `React.memo`, because the object reference changes** **Explanation:** `React.memo` uses shallow comparison. A new object literal `{}` creates a new reference on every render, defeating memoization. Hoist the object outside the component or use `useMemo`.Answer & Explanation
**Answer: B) `React.createElement("button", { className: "btn", onClick: handleClick }, "Submit")`** **Explanation:** JSX is syntactic sugar. Babel (or the React transform) compiles JSX into `React.createElement(type, props, ...children)` calls that produce React element descriptor objects.Answer & Explanation
**Answer: C) Higher-Order Component (HOC)** **Explanation:** A Higher-Order Component (HOC) is a function with the signature `(WrappedComponent) => EnhancedComponent`. It adds cross-cutting concerns (auth guards, logging, theming) without modifying the original component. In modern React, custom hooks have largely replaced HOCs for logic reuse, but HOCs remain common in legacy codebases and libraries.Answer & Explanation
**Answer: B) `React.createPortal`** **Explanation:** `ReactDOM.createPortal(children, domNode)` renders children into any DOM node outside the component\'s parent hierarchy. Despite the separate DOM placement, React event bubbling still follows the React component tree — making portals ideal for modals, tooltips, and dropdown menus that must escape CSS overflow or z-index constraints.Answer & Explanation
**Answer: B) Extend `React.PureComponent` (class) or wrap with `React.memo` (function)** **Explanation:** `React.PureComponent` performs a shallow comparison of props and state for class components. `React.memo` does the same for function components. Both prevent re-renders when props are shallowly unchanged — a lightweight optimization for "leaf" display components that receive only primitives or stable references.## Q. Suppose you are working on the use registration screen. You must call an input blur event from any other press event. Which React hook will you use? - A) useMemo - B) useReducer - C) useContext - D) useRef
Answer & Explanation
**Answer: D) useRef** **Explanation:** `useRef` gives you a direct reference to the underlying DOM element. By attaching the ref to the input (`<input ref={inputRef} />`), you can imperatively call `inputRef.current.blur()` from any other event handler to programmatically trigger the blur event.Answer & Explanation
**Answer: C) useId** **Explanation:** `useId` is a React hook that generates a stable, unique ID that is consistent between server and client renders. It is ideal for associating form elements with labels or any scenario requiring a guaranteed unique identifier per component instance.Answer & Explanation
**Answer: C) Option C - runs whenever `userId` changes** **Explanation:** Option C correctly lists `userId` as the only dependency. Option D is also valid if `fetchUser` is unstable, but Option C is the minimal correct answer for this scenario.Answer & Explanation
**Answer: B) `count` is in the dependency array, so `handleClick` is recreated every time `count` changes, causing the child to re-render** **Explanation:** Because `count` is a dependency, the callback is recreated on each count change, producing a new reference. Use `setCount(prev => prev + 1)` and remove `count` from the dependency array to keep a stable reference.Answer & Explanation
**Answer: B) A memoized value - the sorted array, recomputed only when `items` changes** **Explanation:** `useMemo` caches the result of the computation and only recomputes when a listed dependency changes. This avoids an expensive sort on every render.Answer & Explanation
**Answer: C) Mutating `timerRef.current` does not cause a re-render and persists across renders** **Explanation:** `useRef` returns a mutable container whose `.current` property survives re-renders without triggering them - ideal for storing timers, previous values, or DOM nodes.Answer & Explanation
**Answer: B) When multiple sub-values depend on each other or next state depends on previous state in complex ways** **Explanation:** `useReducer` centralizes complex state transitions into a pure reducer function, making state logic easier to test and reason about compared to multiple independent `useState` calls.Answer & Explanation
**Answer: B) The function name starts with `use` and calls built-in React hooks internally, following the Rules of Hooks** **Explanation:** Custom hooks are plain JavaScript functions whose name begins with `use`. The `use` prefix signals to React\'s linter (eslint-plugin-react-hooks) that the function must follow the Rules of Hooks. They allow stateful logic to be shared across components without changing the component hierarchy or introducing HOC/render-prop complexity.Answer & Explanation
**Answer: B) Hooks must not be called conditionally — the order of hook calls must be identical on every render** **Explanation:** React tracks each hook\'s state by its call order. Placing a hook inside an `if` block means it may or may not execute depending on the condition, corrupting React\'s internal state tracking. The fix is to call the hook unconditionally and use the condition inside it: `const [role, setRole] = useState(isAdmin ? "admin" : "")`.Answer & Explanation
**Answer: C) Whenever the `value` prop of the nearest `ThemeContext.Provider` above it changes** **Explanation:** `useContext` subscribes the component to context updates. React re-renders the consumer whenever the `value` reference on the matching Provider changes. To prevent unnecessary re-renders, memoize the context value with `useMemo` so it only changes when the underlying data changes.## Q. What does the cleanup function returned from `useEffect` do? ```jsx useEffect(() => { const sub = subscribe(userId); return () => sub.unsubscribe(); }, [userId]); ``` - A) It runs before the component mounts for the first time - B) It runs after every re-render before the next effect executes, and on unmount - C) It runs only when the component unmounts - D) It cancels the `subscribe` call before it resolves
Answer & Explanation
**Answer: B) It runs after every re-render before the next effect executes, and on unmount** **Explanation:** React calls the cleanup function before re-running the effect due to a dependency change, and also when the component unmounts. This prevents stale subscriptions and memory leaks.Answer & Explanation
**Answer: B) `useEffect(() => { fetchData(id); }, [id])`** **Explanation:** Listing `id` in the dependency array replicates the `prevProps.id !== this.props.id` guard - the effect only re-runs when `id` changes.Answer & Explanation
**Answer: C) `useLayoutEffect`** **Explanation:** `useLayoutEffect` fires synchronously after all DOM mutations but before the browser paints, allowing DOM measurements and mutations without a visible flash.Answer & Explanation
**Answer: B) Option B — runs once after the initial render only** **Explanation:** `useEffect` with an empty dependency array `[]` runs exactly once after the component\'s first render, mirroring `componentDidMount`. Option A runs after every render (no equivalent lifecycle); Option C also re-runs if `fetchInitialData` reference changes, which is not the same as `componentDidMount`.Answer & Explanation
**Answer: B) Use a cleanup function with an `isMounted` flag or `AbortController` to cancel the update after unmount** **Explanation:** When a component unmounts before an async operation completes, calling `setState` on it causes the warning and a memory leak. The fix is to track whether the component is still mounted or use `AbortController` to cancel the fetch in the cleanup: ```jsx useEffect(() => { const controller = new AbortController(); fetchUser(userId, { signal: controller.signal }).then(user => setUser(user)); return () => controller.abort(); }, [userId]); ```Answer & Explanation
**Answer: B) `React.memo` with a custom comparator function as the second argument** **Explanation:** `React.memo(Component, arePropsEqual)` accepts an optional second argument — a function that receives previous and next props and returns `true` to skip the re-render (same semantics as `shouldComponentUpdate` returning `false`). Without the second argument, `React.memo` performs a default shallow comparison. ```jsx const MyComponent = React.memo(({ value }) =>{value}
,
(prevProps, nextProps) => prevProps.value === nextProps.value
);
```
## Q. React 19 introduces the `use()` hook. What does the following code do? ```jsx import { use } from "react"; function UserProfile({ userPromise }) { const user = use(userPromise); return