Skip to the content.

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.

L2: Intermediate (Junior-Mid / Developer)

Focus: Hooks, state handling, and form patterns.

L3: Advanced (Mid-Senior / Lead)

Focus: Performance, resilience, and code splitting.

L4: Expert (Senior / Architect)

Focus: State management libraries, React 19, and testing.

L5: Framework & Ecosystem (Senior / Lead)

Focus: Next.js, routing, and ecosystem integrations.


# 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?

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.
↥ back to top

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?

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.
↥ back to top

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
}
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.
↥ back to top

Q. Which JSX will return by following the App Component?

function App() {
  return (
    <div>Hello</div>
    <div>World!</div>
  );
}
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>
↥ back to top
## 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
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.
↥ back to top
## Q. A developer writes the following component. What will be rendered in the browser? ```jsx function Greet({ name }) { return

Hello, {name || "World"}!

; } ``` - A) Hello, undefined! - B) Hello, ! - C) Hello, World! - D) A runtime error is thrown
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!`.
↥ back to top
## 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
    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.
    ↥ back to top
    ## 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
    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.
    ↥ back to top
    ## 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
    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`.
    ↥ back to top
    ## 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
    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.
    ↥ back to top
    ## 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
    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.
    ↥ back to top
    ## 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`
    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.
    ↥ back to top
    ## 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`
    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.
    ↥ back to top
    ## # 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
    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.
    ↥ back to top
    ## 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
    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.
    ↥ back to top
    ## 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
    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.
    ↥ back to top
    ## 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`
    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.
    ↥ back to top
    ## 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
    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.
    ↥ back to top
    ## 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
    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.
    ↥ back to top
    ## 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+
    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.
    ↥ back to top
    ## 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
    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.
    ↥ back to top
    ## 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
    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" : "")`.
    ## 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
    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.
    ## # 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
    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.
    ## 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])`
    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.
    ## 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`
    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.
    ## 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`
    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`.
    ## 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`
    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]); ```
    ## 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
    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 ); ```
    ## # 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

    {user.name}

    ; } ``` - A) `use()` converts a class component to a function component - B) `use()` reads a Promise or Context value, suspending the component until the Promise resolves - C) `use()` replaces `useEffect` for data fetching - D) `use()` is equivalent to `await` inside a component
    Answer & Explanation **Answer: B) `use()` reads a Promise or Context value, suspending the component until the Promise resolves** **Explanation:** `use()` is a new React 19 hook that can be called conditionally (unlike other hooks). It integrates with Suspense - the component suspends while the Promise is pending and resumes with the resolved value.
    ## 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 `
    `, including whether a submission is pending - C) The HTTP response status code of the form\'s action - D) The names and values of all form fields
    Answer & Explanation **Answer: B) The submission state of the nearest parent ``, including whether a submission is pending** **Explanation:** `useFormStatus` (react-dom) gives child components access to the form\'s submission state. `pending` is `true` while the form action is executing, enabling progressive-enhancement UX patterns. </details> ## Q. What is the purpose of `useOptimistic` in React 19? ```jsx const [optimisticMessages, addOptimisticMessage] = useOptimistic( messages, (state, newMsg) => [...state, { text: newMsg, sending: true }] ); ``` - A) To batch multiple state updates together - B) To immediately show an optimistic UI update while an async action is in flight, then reconcile with the real result - C) To cache server responses in memory - D) To preload assets before the component mounts
    Answer & Explanation **Answer: B) To immediately show an optimistic UI update while an async action is in flight, then reconcile with the real result** **Explanation:** `useOptimistic` lets you speculatively update the UI before the server confirms the action. Once the action settles, React replaces the optimistic state with the real server state.
    ## Q. A developer migrates a form to use React 19 Server Actions. Which statement is correct? ```jsx // Server component file async function createPost(formData) { "use server"; await db.posts.create({ title: formData.get("title") }); } export default function PostForm() { return <form action={createPost}>; } ``` - A) `"use server"` marks the whole file as a server-only module - B) The `action` prop on `
    ` only accepts a URL string - C) The async function runs on the server; passing it to `action` enables progressive enhancement without a client-side JS handler - D) Server Actions require Redux to manage resulting state
    Answer & Explanation **Answer: C) The async function runs on the server; passing it to `action` enables progressive enhancement without a client-side JS handler** **Explanation:** React 19 Server Actions allow async functions marked `"use server"` to be passed directly to ``. The form works even without JavaScript, and React manages serialization automatically. </details> ## Q. In React 19, what changed about `ref` handling for function components? - A) `ref` is no longer supported on function components - B) Function components can now accept `ref` as a regular prop without `forwardRef` - C) `ref` must be passed as `innerRef` in React 19 - D) `useRef` was replaced by `createRef` in function components
    Answer & Explanation **Answer: B) Function components can now accept `ref` as a regular prop without `forwardRef`** **Explanation:** React 19 deprecates `forwardRef`. Function components can receive `ref` directly in their props, simplifying ref forwarding patterns significantly.
    ## # 5. Redux & State Management
    ## Q. A developer dispatches an action but the UI does not update. What is the most likely bug? ```js // reducer case "ADD_ITEM": state.items.push(action.payload); // mutates state directly return state; ``` - A) `push` is not a valid JavaScript array method - B) The reducer mutates state directly and returns the same reference - React-Redux cannot detect the change - C) Actions must be strings, not objects - D) The component needs to call `forceUpdate()`
    Answer & Explanation **Answer: B) The reducer mutates state directly and returns the same reference - React-Redux cannot detect the change** **Explanation:** Redux reducers must be pure functions that return a new state object. Mutating and returning the same reference means React-Redux\'s shallow equality check sees no change and skips re-rendering. Return `{ ...state, items: [...state.items, action.payload] }` instead.
    ## Q. What is the role of middleware such as `redux-thunk`? ```js const fetchUser = (id) => async (dispatch) => { dispatch({ type: "FETCH_START" }); const user = await api.getUser(id); dispatch({ type: "FETCH_SUCCESS", payload: user }); }; ``` - A) It replaces the Redux store entirely for async operations - B) It allows action creators to return functions (thunks) instead of plain objects, enabling async logic - C) It validates action types at runtime - D) It replaces `combineReducers` for large applications
    Answer & Explanation **Answer: B) It allows action creators to return functions (thunks) instead of plain objects, enabling async logic** **Explanation:** Plain Redux only handles synchronous plain-object actions. `redux-thunk` intercepts function actions and calls them with `dispatch` and `getState`, enabling async workflows.
    ## Q. A developer uses `useSelector` and notices unnecessary re-renders. What is the cause? ```jsx const data = useSelector(state => ({ user: state.user, posts: state.posts, })); ``` - A) `useSelector` does not support object return values - B) A new object literal is returned on every call, so the selector\'s reference always changes, triggering a re-render - C) Both `user` and `posts` need separate stores - D) `useSelector` is not allowed inside function components
    Answer & Explanation **Answer: B) A new object literal is returned on every call, so the selector\'s reference always changes, triggering a re-render** **Explanation:** `useSelector` uses reference equality by default. Returning a new object `{}` each time always fails the equality check. Use separate `useSelector` calls, `shallowEqual` as the second argument, or `createSelector` from Reselect.
    ## Q. What is the purpose of `combineReducers`? ```js const rootReducer = combineReducers({ auth: authReducer, cart: cartReducer, products: productsReducer, }); ``` - A) It merges multiple Redux stores into one - B) It splits a single large reducer into slice functions, each managing its own part of the state tree - C) It enables lazy loading of reducers - D) It prevents reducers from receiving unknown actions
    Answer & Explanation **Answer: B) It splits a single large reducer into slice functions, each managing its own part of the state tree** **Explanation:** `combineReducers` delegates different parts of the state to separate reducer functions. Each reducer only receives and manages its own slice of the state (`state.auth`, `state.cart`, etc.).
    ## # 6. Redux Toolkit
    ## Q. A developer uses `createSlice`. What does `createSlice` automatically generate? ```js const counterSlice = createSlice({ name: "counter", initialState: { value: 0 }, reducers: { increment: state => { state.value += 1; }, decrement: state => { state.value -= 1; }, }, }); ``` - A) Only the reducer function - B) The reducer and corresponding action creators (`counterSlice.actions`) - C) The Redux store and DevTools configuration - D) Async thunks for each reducer
    Answer & Explanation **Answer: B) The reducer and corresponding action creators (`counterSlice.actions`)** **Explanation:** `createSlice` uses Immer under the hood (enabling safe mutation syntax) and auto-generates action creators whose `type` matches `"sliceName/reducerName"` - e.g., `"counter/increment"`.
    ## Q. A developer uses `createAsyncThunk`. What lifecycle actions does it dispatch? ```js export const fetchPosts = createAsyncThunk("posts/fetchAll", async () => { const res = await fetch("/api/posts"); return res.json(); }); ``` - A) Only `posts/fetchAll` - B) `posts/fetchAll/pending`, `posts/fetchAll/fulfilled`, `posts/fetchAll/rejected` - C) `REQUEST`, `SUCCESS`, `FAILURE` - D) `START`, `DONE`, `ERROR`
    Answer & Explanation **Answer: B) `posts/fetchAll/pending`, `posts/fetchAll/fulfilled`, `posts/fetchAll/rejected`** **Explanation:** `createAsyncThunk` automatically dispatches `pending` before the Promise starts, `fulfilled` on resolution, and `rejected` on rejection - matching the FSA lifecycle convention.
    ## Q. A developer uses RTK Query\'s `createApi`. What does the following `useGetUserQuery` hook return? ```js export const { useGetUserQuery } = createApi({ reducerPath: "userApi", baseQuery: fetchBaseQuery({ baseUrl: "/api" }), endpoints: builder => ({ getUser: builder.query({ query: id => `/users/${id}` }), }), }); // In component const { data, isLoading, isError } = useGetUserQuery(userId); ``` - A) A Promise that must be awaited manually - B) An object with `data`, loading/error state, and refetch helpers - auto-fetching when `userId` changes - C) Only the raw fetch response object - D) A Redux action creator
    Answer & Explanation **Answer: B) An object with `data`, loading/error state, and refetch helpers - auto-fetching when `userId` changes** **Explanation:** RTK Query auto-generates hooks that manage fetching, caching, and re-fetching. The hook re-fetches whenever `userId` changes and handles deduplication and cache invalidation automatically.
    ## Q. A developer forgets to add the RTK Query API reducer to the store. What happens? ```js // Missing: [api.reducerPath]: api.reducer const store = configureStore({ reducer: { counter: counterReducer }, middleware: getDefaultMiddleware => getDefaultMiddleware().concat(api.middleware), }); ``` - A) RTK Query works fine - the middleware handles everything - B) RTK Query cannot store its cache; queries will always refetch and cache features will not work - C) The app crashes immediately on startup - D) Only mutations will fail; queries work without the reducer
    Answer & Explanation **Answer: B) RTK Query cannot store its cache; queries will always refetch and cache features will not work** **Explanation:** RTK Query stores its normalized cache in the Redux state tree under `api.reducerPath`. Without the reducer, there is nowhere to persist data and the cache/invalidation system will not function.
    ## Q. A developer wants to respond to `fetchPosts` (a `createAsyncThunk`) inside a `createSlice`. Where should the thunk lifecycle actions be handled? ```js const postsSlice = createSlice({ name: "posts", initialState: { items: [], status: "idle" }, reducers: {}, // ??? handle fetchPosts here }); ``` - A) Inside the `reducers` field with matching action type strings - B) Inside `extraReducers` using the builder callback: `builder.addCase(fetchPosts.fulfilled, ...)` - C) In a separate `createReducer` call outside the slice - D) Directly inside the component with `useDispatch` and a `useEffect`
    Answer & Explanation **Answer: B) Inside `extraReducers` using the builder callback: `builder.addCase(fetchPosts.fulfilled, ...)`** **Explanation:** `extraReducers` is the correct location to handle actions that were generated outside the slice — such as thunk lifecycle actions from `createAsyncThunk`. The builder API provides type-safe methods (`addCase`, `addMatcher`, `addDefaultCase`) to react to `pending`, `fulfilled`, and `rejected` states.
    ## Q. A developer uses `createSelector` from Redux Toolkit (Reselect). What problem does it solve? ```js import { createSelector } from "@reduxjs/toolkit"; const selectFilteredItems = createSelector( [(state) => state.items, (state) => state.filter], (items, filter) => items.filter((item) => item.category === filter) ); ``` - A) It replaces `useSelector` for all state access - B) It memoizes derived data — the result function re-runs only when the input selectors return new values, preventing unnecessary recomputation and re-renders - C) It validates the shape of the Redux state tree - D) It auto-generates action creators for each selector
    Answer & Explanation **Answer: B) It memoizes derived data — the result function re-runs only when the input selectors return new values, preventing unnecessary recomputation and re-renders** **Explanation:** Without memoization, a selector computing derived data (filtered lists, sorted arrays, aggregates) runs on every render. `createSelector` caches the last result and skips recomputation when its input selectors return the same references, improving both CPU usage and render performance when used with `useSelector`.
    ## # 7. Performance Optimization
    ## Q. Alex, an experienced engineer, is optimizing an application\'s event-driven architecture to handle high-frequency events more efficiently. She needs a strategy that will minimize performance bottlenecks and ensure scalability. Which approach should Alex adopt to effectively manage and optimize event handling in the application? - A) Implementing a Debounce function to limit the rate at which events are processed. - B) Using a Global Event Bus to broadcast events across multiple components. - C) Applying the Observer pattern to allow components to state changes efficiently. - D) Integrating a Redux middleware to handle asynchronous events and manage side effects.
    Answer & Explanation **Answer: A) Implementing a Debounce function to limit the rate at which events are processed** **Explanation:** Debouncing limits how often a high-frequency event handler fires by delaying execution until a burst of events has stopped. This directly reduces performance bottlenecks for events like scroll, resize, or keypress. A Global Event Bus adds coupling, the Observer pattern addresses subscriptions not rate-limiting, and Redux middleware handles async side effects rather than event frequency.
    ## Q. Suppose you are working on an inventory management portal. When your product list loads, you don\'t have any control over its state but you want to give high priority to UI updates. Which React feature will help you? - A) useTransition - B) useEffect - C) useMemo - D) useDeferredValue
    Answer & Explanation **Answer: D) useDeferredValue** **Explanation:** `useDeferredValue` is the right choice when you do not control the state (e.g., it comes from a prop or an external source). It creates a deferred copy of the value so React can prioritize urgent UI updates and render the deferred value when the browser is idle. `useTransition` is similar but requires you to own the state update.
    ## Q. A parent re-renders frequently. A child component receives the same props every time. How do you prevent the child from re-rendering? ```jsx function Child({ label }) { return

    {label}

    ; } ``` - A) Wrap `Child` in `React.lazy()` - B) Wrap `Child` in `React.memo()` - it skips re-rendering if props did not shallowly change - C) Use `useEffect` inside `Child` to guard rendering - D) Move `Child` into the parent\'s render method
    Answer & Explanation **Answer: B) Wrap `Child` in `React.memo()` - it skips re-rendering if props did not shallowly change** **Explanation:** `React.memo` is a higher-order component that memoizes the rendered output. If the next props shallowly equal the previous props, React reuses the last render and skips the child\'s reconciliation.
    ## Q. A developer profiles the app and sees a slow computation running on every render. Which hook should they apply? ```jsx function Dashboard({ transactions }) { const total = transactions.reduce((sum, t) => sum + t.amount, 0); // expensive return
    Total: {total}
    ; } ``` - A) `useEffect` - run the computation as a side effect - B) `useCallback` - memoize the reduce function - C) `useMemo` - cache the computed `total` and recompute only when `transactions` changes - D) `useRef` - store the total in a ref
    Answer & Explanation **Answer: C) `useMemo` - cache the computed `total` and recompute only when `transactions` changes** **Explanation:** `useMemo(() => transactions.reduce(...), [transactions])` ensures the expensive reduction only runs when `transactions` changes, not on every render.
    ## Q. A developer uses `useTransition`. What does `isPending` indicate? ```jsx const [isPending, startTransition] = useTransition(); function handleSearch(e) { startTransition(() => setQuery(e.target.value)); } ``` - A) The network request is in-flight - B) React is still processing the low-priority transition update - C) The component is suspended in a Suspense boundary - D) The input field has unsaved changes
    Answer & Explanation **Answer: B) React is still processing the low-priority transition update** **Explanation:** `useTransition` marks an update as non-urgent. `isPending` is `true` while React is rendering the deferred update, allowing you to show a loading indicator without blocking the input.
    ## # 8. Context API
    ## Q. Suppose you have a three-level component hierarchy and must pass a value from the top component to the leaf component, but using props shall take extra code. How can you achieve this without using props? - A) Use the Context API - B) Use the Event Bus - C) Use a common file for this type of values - D) Use the Custom component
    Answer & Explanation **Answer: A) Use the Context API** **Explanation:** The React Context API is designed exactly for this scenario — passing data through a component tree without having to thread props through every intermediate level (prop drilling). Create a context with `React.createContext`, wrap the tree in a `Provider`, and any descendant can consume the value with `useContext`.
    ## Q. A developer wraps the app in a `ThemeContext.Provider`. A deeply nested component reads the theme. What happens when the theme value changes? ```jsx <ThemeContext.Provider value={theme}> </ThemeContext.Provider> ``` - A) Only the direct children of `Provider` re-render - B) All components that consume the context via `useContext(ThemeContext)` re-render - C) The entire component tree re-renders regardless of context consumption - D) Context changes do not trigger re-renders; components must call `forceUpdate`
    Answer & Explanation **Answer: B) All components that consume the context via `useContext(ThemeContext)` re-render** **Explanation:** React re-renders every component that called `useContext(ThemeContext)` whenever the `value` reference changes. Components that do not consume the context are not affected.
    ## Q. A developer notices that changing an unrelated state in the Provider\'s parent causes all consumers to re-render. What is the fix? ```jsx function App() { const [count, setCount] = useState(0); const theme = { color: "blue" }; // new reference every render return ( <ThemeContext.Provider value={theme}> </ThemeContext.Provider> ); } ``` - A) Move context into Redux - B) Use `useMemo` to stabilize the `theme` object reference - C) Split the context into two providers - D) Switch to a class component
    Answer & Explanation **Answer: B) Use `useMemo` to stabilize the `theme` object reference** **Explanation:** A new `theme` object is created on every render, causing all consumers to re-render. `const theme = useMemo(() => ({ color: "blue" }), [])` produces a stable reference and prevents unnecessary consumer updates.
    ## # 9. Error Boundaries
    ## Q. Alex, a software engineer, encounters an unhandled promise rejection error in an application. He observes that while the app displays an error message, the error details are not logged effectively for debugging. How can Alex ensure comprehensive error logging for unhandled promise rejections? - A) Use window.addEventListener to listen for unhandled promise rejections and log them. - B) Configure the app to catch error in async functions using try-catch blocks. - C) Implement a global error boundary component to handle and log all errors - D) Integrate a logging library that automatically captures unhandled promises rejections.
    Answer & Explanation **Answer: A) Use window.addEventListener to listen for unhandled promise rejections and log them** **Explanation:** `window.addEventListener('unhandledrejection', handler)` is the standard browser API for globally capturing unhandled promise rejections. The event object provides the rejected `reason`, enabling comprehensive logging. Error Boundaries do not catch async/promise errors, and `try-catch` only works when applied locally around each async call.
    ## Q. A developer wraps a component tree in an Error Boundary. Which types of errors does it catch? ```jsx class ErrorBoundary extends React.Component { state = { hasError: false }; static getDerivedStateFromError() { return { hasError: true }; } render() { return this.state.hasError ? : this.props.children; } } ``` - A) All JavaScript errors anywhere in the application - B) Errors thrown during rendering, in lifecycle methods, and in constructors of child components - C) Errors thrown inside event handlers - D) Network errors from `fetch` calls
    Answer & Explanation **Answer: B) Errors thrown during rendering, in lifecycle methods, and in constructors of child components** **Explanation:** Error Boundaries catch errors during React\'s render phase and lifecycle methods. They do NOT catch errors in event handlers (use `try/catch` there), async code, or server-side rendering.
    ## Q. What is the difference between `getDerivedStateFromError` and `componentDidCatch`? - A) They are identical; either can be used - B) `getDerivedStateFromError` is used to render a fallback UI (render phase); `componentDidCatch` is used to log error information (commit phase) - C) `componentDidCatch` renders the fallback; `getDerivedStateFromError` only logs - D) `getDerivedStateFromError` replaces `componentDidCatch` in React 18+
    Answer & Explanation **Answer: B) `getDerivedStateFromError` is used to render a fallback UI (render phase); `componentDidCatch` is used to log error information (commit phase)** **Explanation:** `getDerivedStateFromError` runs during rendering so it can update state to show a fallback. `componentDidCatch` runs after the tree has re-rendered and is the right place to call error reporting services.
    ## # 10. Code Splitting & Lazy Loading
    ## Q. You are working on a real-time stock market web application. As your dashboard code is too lengthy, it takes excess time to load. How will you resolve this issue? - A) Remove a few features from the page - B) Split the code into small modules and import it as per the requirements. - C) Remove a few data load requests and make it light - D) Limit data that increases the load on the dashboard.
    Answer & Explanation **Answer: B) Split the code into small modules and import it as per the requirements** **Explanation:** Code splitting with `React.lazy()` and dynamic `import()` allows the dashboard to load only the code needed for the initial view, deferring heavier modules until they are required. This reduces the initial bundle size and improves load time without removing features or limiting data.
    ## Q. Alex, a software developer, is working on an application where she needs to implement a seamless transition between pages. She is considering using the Transition API to enhance the user experience. Which approach should Alex take to achieve smooth transitions in her application? - A) Use the Transition API\'s startTransition function to update the state that triggers transitions. - B) Apply the ReactDom.createRoot method to manage the rendering of transition states. - C) Utilize React.StrictMode to detect potential issues during transitions. - D) Implement React.lazy for dynamic imports to handle page transitions.
    Answer & Explanation **Answer: A) Use the Transition API\'s startTransition function to update the state that triggers transitions** **Explanation:** `startTransition` (from `useTransition` or `React.startTransition`) marks a state update as a non-urgent transition, allowing React to keep the current UI responsive while preparing the new page in the background. This is the correct way to achieve smooth page-to-page transitions with the Transition API.
    ## Q. Alex, a software developer, is working on an application where she is utilizing Suspense for handling data fetching. Despite configuring Suspense she observes that her component does not render immediately when waiting for data. She is puzzled about the potential reasons behind this delay in rendering. What could be the reason for this behavior? - A) The delay in rendering might be due to network latency or slow data fetching, rather than an issue with how Suspense is used or configured in the application. - B) Alex\'s component could be using an outdated version that does not support the latest features required for Suspense to handle data fetching and rendering efficiently, resulting in the delay. - C) The Suspense component configuration might be incorrect or incomplete. If Suspense is not properly set up, it could lead to unexpected delays in rendering the component and handling asynchronous operations. - D) Alex might not have wrapped her component properly with a Suspense component. This is crucial as Suspense manages asynchronous data fetching and ensures that the fallback UI is shown until the data is fully loaded and the component is ready to render.
    Answer & Explanation **Answer: D) Alex might not have wrapped her component properly with a Suspense component** **Explanation:** Suspense requires components that perform asynchronous data fetching to be wrapped inside a `` boundary with a `fallback` prop. Without proper wrapping, the component will not know to show a fallback UI while data loads, resulting in unexpected rendering behavior. </details> ## Q. A developer lazy-loads a component. Why is `Suspense` required? ```jsx const LazyChart = React.lazy(() => import("./Chart")); function Dashboard() { return ( <Suspense fallback={}> ); } ``` - A) `Suspense` fetches the chunk from the network - B) While the `Chart` chunk is downloading, the component suspends; `Suspense` provides the fallback UI during that pause - C) `Suspense` caches the chunk so it is only downloaded once - D) Without `Suspense`, `React.lazy` defaults to eager loading
    Answer & Explanation **Answer: B) While the `Chart` chunk is downloading, the component suspends; `Suspense` provides the fallback UI during that pause** **Explanation:** `React.lazy` throws a Promise while the module is loading. A `Suspense` boundary catches that Promise and renders its `fallback` prop until the Promise resolves and the component is ready.
    ## Q. A developer code-splits by route. Which approach is correct for React Router v6? ```jsx // Option A const Home = React.lazy(() => import("./Home")); <Route path="/" element={<Suspense fallback={}></Suspense>} /> // Option B const Home = import("./Home"); <Route path="/" element={} /> ``` - A) Option A is correct - B) Option B is correct - C) Both are equivalent - D) Neither is valid - React Router handles code splitting automatically
    Answer & Explanation **Answer: A) Option A is correct** **Explanation:** Dynamic `import()` must be wrapped in `React.lazy()` and the resulting component must be rendered inside a `Suspense` boundary. Option B creates a Promise, not a React component.
    ## # 11. Forms & Controlled Components
    ## Q. A developer builds a controlled input. What is missing? ```jsx function SearchBox() { const [query, setQuery] = useState(""); return <input type="text" value={query} />; } ``` - A) The `defaultValue` attribute - B) An `onChange` handler - without it the input is read-only and cannot be updated - C) A `ref` to read the input value - D) `name` attribute for the controlled input
    Answer & Explanation **Answer: B) An `onChange` handler - without it the input is read-only and cannot be updated** **Explanation:** In a controlled component, React drives the input value via the `value` prop. Without `onChange` calling `setQuery`, user keystrokes are ignored and the input appears frozen.
    ## Q. A developer uses React Hook Form. What advantage does it have over fully controlled forms? ```jsx const { register, handleSubmit } = useForm(); <form onSubmit={handleSubmit(onSubmit)}> <input {...register("email")} /> </form> ``` - A) It eliminates the need for any validation logic - B) It uses uncontrolled inputs with refs by default, reducing re-renders on every keystroke - C) It replaces the native HTML `` element - D) It is only useful for very large forms
    Answer & Explanation **Answer: B) It uses uncontrolled inputs with refs by default, reducing re-renders on every keystroke** **Explanation:** React Hook Form avoids re-rendering on each keystroke by managing values through DOM refs instead of React state, significantly improving performance for complex forms.
    ## Q. A developer wants to manage multiple form inputs with a single state object. Which pattern is correct? ```jsx // Option A const [form, setForm] = useState({ name: "", email: "" }); function handleChange(e) { setForm({ ...form, [e.target.name]: e.target.value }); } // Option B const [form, setForm] = useState({ name: "", email: "" }); function handleChange(e) { form[e.target.name] = e.target.value; setForm(form); } ``` - A) Option A — uses computed property names to update only the changed field immutably - B) Option B — directly mutates the state object then sets it - C) Both are equivalent - D) Neither is valid; each input requires its own `useState`
    Answer & Explanation **Answer: A) Option A — uses computed property names to update only the changed field immutably** **Explanation:** `[e.target.name]` is a computed property key that dynamically targets the right field. The spread `...form` ensures the rest of the state is preserved immutably. Option B mutates the existing state object directly and passes the same reference, so React may not detect the change and re-render.
    ## Q. What is the key difference between a controlled and an uncontrolled component? ```jsx // Controlled const [val, setVal] = useState(""); <input value={val} onChange={e => setVal(e.target.value)} /> // Uncontrolled const inputRef = useRef(); <input defaultValue="" ref={inputRef} /> ``` - A) Controlled components are faster because they skip React reconciliation - B) In a controlled component, React owns the value via state; in an uncontrolled component, the DOM owns the value and it is read via a ref - C) Uncontrolled components do not support `onChange` events - D) `defaultValue` is only valid in controlled components
    Answer & Explanation **Answer: B) In a controlled component, React owns the value via state; in an uncontrolled component, the DOM owns the value and it is read via a ref** **Explanation:** Controlled components keep the input value in React state, making it the single source of truth. Uncontrolled components let the DOM manage the value — you read it imperatively via `ref.current.value` (e.g., on submit). Controlled inputs are preferred when you need immediate validation or conditional rendering based on input value.
    ## Q. A developer renders a ` ); } ``` - A) `` and there is no `onChange` handler — the selection is uncontrolled - C) Each `