Knowledge / Computer Science and Engineering / Front-end frameworks: React basics

Front-end frameworks: React basics

Computer Science and Engineering (B.E./B.Tech) · Web, cloud and design · free study notes for exams, placements and interviews

In short

React is an open-source JavaScript library (created at Facebook, now Meta, released 2013) for building user interfaces as a tree of reusable components whose output is a pure function of their props and state. Instead of hand-editing the DOM, the developer declares what the screen should look like for a given state, and React computes the minimum set of real DOM changes using a virtual DOM and a reconciliation algorithm. It is the dominant front-end skill demanded in Indian hiring — TCS, Infosys, Wipro, Cognizant, Accenture, HCLTech, LTIMindtree, Zoho, Freshworks, Zomato, Swiggy, Flipkart, PhonePe and almost every product startup list React in fresher JD's — and appears in university syllabi as "Full Stack Development" / "Web Technologies" electives under the AICTE model curriculum. GATE CS does not examine React directly, but university end-semester papers, lab vivas and placement coding rounds do. A fresher is typically asked to explain the virtual DOM, write a counter or to-do list with hooks, and describe how data flows between components.

Explained

Why React: declarative UI and the virtual DOM

JSX and elements

Components, props and state

Hooks (React 16.8 onwards)

Rendering: lists, keys, conditionals, forms and events

Ecosystem, tooling and performance

Key points

Formulas and examples

Core identity: UI = f(state, props) — the rendered output is a pure function of current state and props.
DOM operations per update ≈ number of changed nodes, not total nodes — reconciliation cost O(n) in tree size n, with keyed list matching.
Re-render trigger: component re-renders when (its own state changes) OR (its props change) OR (its parent re-renders) OR (a consumed context value changes).
useCallback(fn, deps) ≡ useMemo(() => fn, deps); React.memo compares props shallowly with Object.is.
Bundle budget rule of thumb: initial JS under ~200 KB gzipped for acceptable load on a 4G Indian mobile connection; split the rest with React.lazy.

Example 1 — Counter with useState (the standard lab/interview warm-up)

import { useState } from 'react';

function Counter({ step = 1 }) {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(c => c + step)}>+{step}</button>
      <button onClick={() => setCount(0)}>Reset</button>
    </div>
  );
}

Trace with step = 1, three clicks on "+1": initial render count = 0 → click 1 schedules 0+1 → re-render shows 1 → click 2 shows 2 → click 3 shows 3. If the handler were written setCount(count + 1); setCount(count + 1); in one click, both calls read the same stale count = 0, so the result is 1, not 2; with the functional form setCount(c => c + 1) twice the result is 2.

Example 2 — Virtual DOM saving: counting real DOM writes

A table of 1,000 rows; one cell's text changes.

ApproachReal DOM nodes touchedApprox. work
Re-render table with innerHTML1,000 rows rebuilt (≈ 5,000 nodes at 5 cells/row)Full re-parse, layout and paint
React with stable keys1 text node patched≈ 5,000 VDOM object comparisons (cheap JS) + 1 DOM write

If one real DOM mutation plus layout costs about 1 ms and one VDOM node comparison about 0.001 ms, the imperative rebuild ≈ 5,000 × 1 ms = 5,000 ms, while React ≈ (5,000 × 0.001) + 1 = 6 ms — roughly 830× faster. (Time figures are illustrative orders of magnitude, not measured constants; the ratio of DOM writes is exact: 1 versus 5,000.)

Example 3 — Fetching with useEffect, including cleanup and the three UI states

function JobList({ city }) {
  const [jobs, setJobs] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const ctrl = new AbortController();
    setLoading(true);
    fetch(`/api/jobs?city=${city}`, { signal: ctrl.signal })
      .then(r => { if (!r.ok) throw new Error(r.status); return r.json(); })
      .then(data => { setJobs(data); setError(null); })
      .catch(e => { if (e.name !== 'AbortError') setError(e.message); })
      .finally(() => setLoading(false));
    return () => ctrl.abort();          // cleanup on unmount or city change
  }, [city]);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Could not load: {error}</p>;
  if (jobs.length === 0) return <p>No jobs in {city}</p>;
  return <ul>{jobs.map(j => <li key={j.id}>{j.title} - Rs {j.ctc}</li>)}</ul>;
}

Effect-run count when the user changes city twice: mount with city='Kochi' → 1 run; change to 'Pune' → cleanup + run 2; change to 'Delhi' → cleanup + run 3. Total 3 effect runs, 3 cleanups (the last on unmount). With [] instead of [city] the list would stay stuck on Kochi — a classic exam trap.

Example 4 — Index as key: the off-by-one bug, counted

List ['A','B','C'] rendered as <Input key={index} defaultValue={item}/>; the user types into row 1 (B). Now 'A' is deleted.

Row after deleteItemKey with indexKey with idWhat React does
0B0id-Bindex: reuses old row 0 (A's node, still showing "A") — wrong text
1C1id-Cindex: reuses old row 1 (B's node, holding the typed text) — wrong text
—A removed2 unmountedid-A unmountedindex: the *last* node is destroyed; id: React removes exactly A's node

With index keys, 2 of 2 remaining rows show the DOM state left by whichever item previously sat at that index; with stable ids, 0 of 2 are wrong and only 1 node is removed.

Example 5 — Render-count arithmetic with React.memo

Parent holds count and renders <Child data={list} onPick={handlePick}/>. The parent's state updates 10 times.

SetupChild renders out of 10 parent renders
Plain Child10 — a parent re-render re-renders children by default
React.memo(Child), onPick defined inline10 — a new function identity each render breaks shallow equality
React.memo(Child) + useCallback(handlePick, []) + useMemo for list1 — only the first render

Saving = 9 of 10 child renders avoided (90%). If each child render costs 4 ms, time saved = 9 × 4 = 36 ms.

Where it is used

Interview questions

Common mistakes

Related topics

Web fundamentals: HTML, CSS and JavaScript · REST APIs · Back-end development with Node.js · Authentication and authorisation: sessions, OAuth and JWT · System design basics for freshers · Caching, queues and CDNs

Open in the Knowledge reader →Find jobs →