Episode 2 — React Frontend Architecture NextJS / 2.1 — Introduction to React

2.1 — Introduction to React: Quick Revision

Compact cheat sheet. Print-friendly. One concept per line.


How to Use This Material

  1. Skim before an interview — refresh all concepts in 10 minutes.
  2. Cover the right column — test yourself on definitions.
  3. Star items you can't recall — those need deeper review.
  4. Pair with sub-topic files — this is a summary, not a substitute.

2.1.a — Why React Exists

ConceptKey Point
Core problemKeeping UI in sync with data at scale is hard with vanilla JS
Created byFacebook (Meta), 2013 — solving notification count bugs
React's formulaUI = f(state) — UI is a function of state
DeclarativeYou describe WHAT the UI should look like, not HOW to update it
Component-basedUI built from independent, reusable, composable pieces
Unidirectional flowData flows down (props), events flow up (callbacks)
Virtual DOMLightweight JS copy of DOM — enables efficient diffing
When NOT to useSimple static pages, SEO-critical content-only sites (without SSR framework)
EvolutionClasses → Hooks (2019) → Server Components (2023+)

2.1.b — Declarative vs Imperative UI

ConceptKey Point
ImperativeStep-by-step instructions — "find element, change text, add class"
DeclarativeDesired end state — "this component should show count"
React is declarativeYou describe UI for given state; React handles DOM updates
Why declarative winsPredictable, debuggable, composable, maintainable
UI = f(state)Same state → always same UI output
DebuggingState wrong → bug in update logic. UI wrong but state correct → bug in render
Declarative elsewhereSQL (SELECT), CSS (rules), HTML (structure)
Imperative in ReactStill needed for: focus, scroll, measurements, third-party DOM libs
Key escape hatchuseRef + useEffect for imperative DOM access

2.1.c — Single Page Applications

ConceptKey Point
SPA definitionOne HTML page; JavaScript handles all navigation and rendering
Traditional MPAEvery navigation → full page reload from server
Client-side routingURL changes via History API; no server request for new pages
Initial loadSPA: heavy (JS bundle). MPA: light (just HTML)
Subsequent navSPA: instant (no reload). MPA: slow (full page fetch)
SEO challengeSearch engines may not execute JavaScript to see content
Blank page problemUser sees nothing until JS downloads, parses, and executes
SolutionsSSR (Next.js), SSG, code splitting, prerendering
Best forInteractive apps (dashboards, social, e-commerce)
Not ideal forContent-heavy sites where SEO is critical (without SSR)

2.1.d — Real DOM vs Virtual DOM

ConceptKey Point
Real DOMBrowser's actual element tree — heavy objects, triggers reflow/repaint
Virtual DOMLightweight JS objects mirroring DOM structure
Why real DOM is slowMutations trigger: style recalc → layout → paint → composite
React's processNew VDOM → diff with old VDOM → minimal real DOM patches
ReconciliationReact's diffing algorithm comparing old and new virtual trees
BatchingMultiple state updates combined into single DOM update
Keys in listsHelp React identify which items changed/moved/were removed
VDOM overheadAdds memory + CPU cost; not faster than hand-optimized DOM
VDOM benefitConsistently good performance without manual optimization
AlternativesSvelte (compile-time), SolidJS (fine-grained reactivity) — no VDOM

2.1.e — Setting Up React with Vite

ConceptKey Point
ViteFast build tool using native ES modules for dev server
Why not CRACRA is deprecated, slow (Webpack bundles everything upfront)
Create projectnpm create vite@latest my-app -- --template react
Start dev servercd my-app && npm install && npm run dev
Default porthttp://localhost:5173
HMRHot Module Replacement — updates module without full reload
vite.config.jsConfigure plugins, port, proxy, aliases
Production buildnpm run build → outputs to dist/ folder
Preview buildnpm run preview → serves production build locally
Dependenciesreact, react-dom in deps; vite, @vitejs/plugin-react in devDeps

2.1.f — Project Structure Breakdown

File/FolderPurpose
index.htmlEntry HTML file (at root in Vite, not in public/)
src/main.jsxJavaScript entry — mounts React app to DOM
src/App.jsxRoot component of the application
src/assets/Images, fonts imported by components (processed by Vite)
public/Static files served as-is (favicon, robots.txt)
node_modules/Installed dependencies (never edit, never commit)
package.jsonProject metadata, scripts, dependencies
vite.config.jsVite configuration

Key distinction: src/assets/ → Vite processes (hashes, optimizes). public/ → served unchanged.

ReactDOM.createRoot(document.getElementById('root'))  // find <div id="root">
  .render(<App />)                                     // render App into it

2.1.g — JSX Syntax Rules

RuleExample
Single root elementWrap in <div> or <>...</> (Fragment)
className not class<div className="box">
htmlFor not for<label htmlFor="email">
camelCase attributesonClick, tabIndex, autoFocus
Style as objectstyle={{ color: 'red', fontSize: '14px' }}
Self-closing tags<img />, <input />, <br />
JS expressions in {}<p>{user.name}</p>, <p>{2 + 2}</p>
No if statements in JSXUse ternary: {isOn ? 'Yes' : 'No'}
Conditional render{show && <Modal />}
List render{items.map(item => <li key={item.id}>{item.name}</li>)}
JSX compiles toReact.createElement(type, props, ...children)
Boolean/null/undefinedNot rendered — {false}, {null} produce nothing

2.1.h — Component-Based Architecture

ConceptKey Point
ComponentIndependent, reusable UI function returning JSX
Component treeHierarchical parent-child structure; App is root
Data flowProps down (parent→child), callbacks up (child→parent)
PresentationalRenders UI from props, no data fetching, highly reusable
ContainerManages state/data, passes to presentational children
Modern patternCustom hooks replace container components
When to split>100 lines, multiple responsibilities, reuse opportunity
Single responsibilityOne component = one job
Composition > inheritanceWrap/configure components, don't extend classes
children propJSX between open/close tags becomes children
Compound componentsRelated components sharing implicit state (Tabs + TabPanel)
File organizationType-based (small), Feature-based (medium+), Atomic (design systems)
NamingPascalCase always: ProductCard, UserAvatar
Prop drillingPassing props through many layers → use Context to solve
Anti-patternsGod components, prop explosion, premature abstraction
Reusability spectrumHardcoded → Configurable → Flexible → Render props → Headless

Core Formulas & Patterns

// Minimal component
function Greeting({ name }) {
  return <h1>Hello, {name}!</h1>;
}

// Component with state
function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}

// Conditional rendering
{isLoggedIn ? <Dashboard /> : <LoginPage />}
{error && <ErrorMessage text={error} />}

// List rendering
{items.map(item => <Card key={item.id} data={item} />)}

// Composition via children
<Card><p>Any content here</p></Card>

// Callback communication (child → parent)
<SearchBar onSearch={(query) => setSearchTerm(query)} />

Decision Quick-Reference

Need to share state between siblings?  → Lift state to parent
Need data in deeply nested component?  → Context API
Component > 100 lines?                 → Consider splitting
Same JSX pattern repeated?             → Extract a component
Complex data fetching logic?           → Extract custom hook
Multiple visual variants of same thing? → Use variant prop
Static content site?                   → Maybe don't need React
Interactive data-heavy app?            → React is a great choice
Starting new project?                  → Next.js + Vite (via Next)

Quick revision for Topic 2.1 — Introduction to React. For deep explanations, see the individual sub-topic files.