Exambodh - Practice Aptitude, Reasoning & GK Questions
UPlay Quiz
Javascript questions and answers

React Interview Questions and Answers 2026 | SSR, CSR, Hooks, Virtual DOM

By Exambodh Team2 Jun 20265 min read14 Views


React Interview Questions Explained in Easy Way

In this article, we will understand important React interview questions like Virtual DOM, Reconciliation, SSR vs CSR, Hooks, Caching, Lazy Loading, React 19 features, and one practical counter component with validation.

1. What is React Reconciliation? How does Virtual DOM work?

What is Virtual DOM?

Virtual DOM is a lightweight JavaScript copy of the real DOM. React keeps this copy in memory to make UI updates faster.

State changes → New Virtual DOM → Compare with old Virtual DOM → Update only changed part

What is Reconciliation?

Reconciliation is the process where React compares the old Virtual DOM with the new Virtual DOM and updates only the required part of the real DOM.

function App() {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <h1>Counter</h1>
      <p>{count}</p>
      <button => setCount(count + 1)}>
        Increase
      </button>
    </div>
  );
}

When count changes, React does not update the full page. It only updates the changed text inside the paragraph.

Role of Key

Keys help React identify which list item changed, added, or removed.

{items.map(item => (
  <li key={item.id}>{item.name}</li>
))}

Interview Answer: React Reconciliation compares old and new Virtual DOM and updates only the changed parts in the real DOM.

2. What is SSR vs CSR? Which one is faster and why?

CSR: Client-Side Rendering

In CSR, browser downloads JavaScript first, then React renders the UI in the browser.

Browser → Empty HTML → Download JS → Run React → Fetch Data → Show UI

SSR: Server-Side Rendering

In SSR, server prepares the HTML first and sends ready content to the browser.

Browser Request → Server renders HTML → Browser shows ready page

Which is faster?

SSR is usually faster for the first page load because browser receives ready HTML. CSR can feel faster after loading because page interactions happen inside the browser.

PointSSRCSRRenderingServerBrowserInitial LoadFastSlowSEOExcellentWeak/MediumBest ForBlogs, SEO pages, product pagesDashboards, apps, admin panels

Interview Answer: SSR is faster for initial load because server sends ready HTML. CSR is slower initially because browser must load and execute JavaScript first.

3. What are React Hooks? Explain useEffectEvent hook.

Hooks are special functions that allow functional components to use React features like state, lifecycle, context, refs, and memoization.

  • useState: Manage state
  • useEffect: Handle side effects
  • useRef: Store mutable values
  • useMemo: Memoize expensive calculation
  • useCallback: Memoize functions
  • useContext: Use global context
function Counter() {
  const [count, setCount] = React.useState(0);

  return (
    <button => setCount(count + 1)}>
      Count: {count}
    </button>
  );
}

What is useEffectEvent?

useEffectEvent is used when we want to access latest props or state inside an effect without re-running that effect again and again.

import { useEffect, useEffectEvent } from "react";

function Counter({ count }) {
  const logCount = useEffectEvent(() => {
    console.log("Current count:", count);
  });

  useEffect(() => {
    const id = setInterval(() => {
      logCount();
    }, 1000);

    return () => clearInterval(id);
  }, []);

  return <p>{count}</p>;
}

Interview Answer: Hooks allow functional components to use React features. useEffectEvent helps access latest state or props inside effects without unnecessary effect re-runs.

4. How does caching work in React applications?

Caching means storing data temporarily so the app does not need to fetch or calculate the same thing again and again.

Types of Caching

  • Browser Cache: Stores images, CSS, JS files
  • API Cache: Stores API response
  • React Query Cache: Stores server data in memory
  • Memoization: Stores calculated values
  • Next.js Cache: Caches server fetch result
import { useQuery } from "@tanstack/react-query";

function Users() {
  const { data, isLoading } = useQuery({
    queryKey: ["users"],
    queryFn: () => fetch("/api/users").then(res => res.json()),
    staleTime: 1000 * 60 * 5,
  });

  if (isLoading) return <p>Loading...</p>;

  return data.map(user => (
    <p key={user.id}>{user.name}</p>
  ));
}
const total = useMemo(() => {
  return calculateTotal(items);
}, [items]);

Interview Answer: Caching stores data, assets, or calculated results to avoid repeated work. It improves speed, reduces API calls, and gives better user experience.

5. How do you implement lazy loading in React?

Lazy loading means loading component, route, image, or library only when it is needed. It reduces initial bundle size.

import React, { Suspense, lazy } from "react";

const Dashboard = lazy(() => import("./Dashboard"));

function App() {
  return (
    <Suspense fallback={<p>Loading dashboard...</p>}>
      <Dashboard />
    </Suspense>
  );
}

Lazy Loading Image

<img src="""/banner.jpg""" alt="Banner" loading="lazy" />

Next.js Dynamic Import

import dynamic from "next/dynamic";

const Chart = dynamic(() => import("./Chart"), {
  loading: () => <p>Loading chart...</p>,
  ssr: false,
});

Interview Answer: Lazy loading loads components or assets only when needed. In React, we use React.lazy, Suspense, dynamic import, and image lazy loading.

6. What’s new in React 19?

React 19 focuses on better async handling, improved forms, actions, optimistic UI, and easier server/client integration.

Important React 19 Features

  • Actions: Easier async form submission
  • useActionState: Manage form state and pending state
  • useOptimistic: Show instant UI before server response
  • use API: Read promises and context
  • Ref as Prop: Easier ref passing
  • Metadata Support: Support for title and meta tags
import { useActionState } from "react";

function Form() {
  async function submit(prevState, formData) {
    const name = formData.get("name");

    if (!name) {
      return { error: "Name is required" };
    }

    return { success: "Saved successfully" };
  }

  const [state, formAction, isPending] = useActionState(submit, {});

  return (
    <form action={formAction}>
      <input name="name" />

      <button disabled={isPending}>
        {isPending ? "Saving..." : "Save"}
      </button>

      {state.error && <p>{state.error}</p>}
      {state.success && <p>{state.success}</p>}
    </form>
  );
}

Interview Answer: React 19 introduces better form actions, useActionState, useOptimistic, use API, improved ref handling, and better async UI management.

7. Build Increment / Decrement Component with Validation

This component allows user to enter a number, increment it, decrement it, and show error message for empty or non-numeric input.

import React, { useState } from "react";

export default function CounterWithValidation() {
  const [value, setValue] = useState("0");
  const [error, setError] = useState("");

  const validateNumber = input => {
    if (input.trim() === "") {
      return "Value is required";
    }

    if (isNaN(Number(input))) {
      return "Please enter a valid number";
    }

    return "";
  };

  const handleChange = e => {
    const inputValue = e.target.value;
    setValue(inputValue);

    const errorMessage = validateNumber(inputValue);
    setError(errorMessage);
  };

  const handleIncrement = () => {
    const errorMessage = validateNumber(value);

    if (errorMessage) {
      setError(errorMessage);
      return;
    }

    setValue(String(Number(value) + 1));
    setError("");
  };

  const handleDecrement = () => {
    const errorMessage = validateNumber(value);

    if (errorMessage) {
      setError(errorMessage);
      return;
    }

    setValue(String(Number(value) - 1));
    setError("");
  };

  return (
    <div className="max-w-sm rounded-2xl border border-gray-200 bg-white p-6 shadow-sm">
      <h2 className="mb-4 text-xl font-bold">Counter</h2>

      <input
        type="text"
        value={value}
        placeholder="Enter number"
        className={`w-full rounded-lg border px-4 py-3 outline-none ${
          error ? "border-red-500" : "border-gray-300"
        }`}
      />

      {error && (
        <p className="mt-2 text-sm text-red-600">
          {error}
        </p>
      )}

      <div className="mt-5 flex gap-3">
        <button
          className="rounded-lg bg-gray-900 px-4 py-2 text-white"
        >
          Decrement
        </button>

        <button
          className="rounded-lg bg-indigo-600 px-4 py-2 text-white"
        >
          Increment
        </button>
      </div>

      <p className="mt-4 text-gray-700">
        Current Value: {error ? "Invalid input" : value}
      </p>
    </div>
  );
}

Explanation

  • value: stores current input value
  • error: stores validation message
  • validateNumber: checks empty and non-numeric input
  • handleIncrement: increases valid number by 1
  • handleDecrement: decreases valid number by 1

Interview Answer: This component uses useState for input and error state. It validates input before incrementing or decrementing the number.

Share this article: