2.1 — Introduction to React: Quick Revision
Compact cheat sheet. Print-friendly. One concept per line.
How to Use This Material
- Skim before an interview — refresh all concepts in 10 minutes.
- Cover the right column — test yourself on definitions.
- Star items you can't recall — those need deeper review.
- Pair with sub-topic files — this is a summary, not a substitute.
2.1.a — Why React Exists
| Concept | Key Point |
|---|
| Core problem | Keeping UI in sync with data at scale is hard with vanilla JS |
| Created by | Facebook (Meta), 2013 — solving notification count bugs |
| React's formula | UI = f(state) — UI is a function of state |
| Declarative | You describe WHAT the UI should look like, not HOW to update it |
| Component-based | UI built from independent, reusable, composable pieces |
| Unidirectional flow | Data flows down (props), events flow up (callbacks) |
| Virtual DOM | Lightweight JS copy of DOM — enables efficient diffing |
| When NOT to use | Simple static pages, SEO-critical content-only sites (without SSR framework) |
| Evolution | Classes → Hooks (2019) → Server Components (2023+) |
2.1.b — Declarative vs Imperative UI
| Concept | Key Point |
|---|
| Imperative | Step-by-step instructions — "find element, change text, add class" |
| Declarative | Desired end state — "this component should show count" |
| React is declarative | You describe UI for given state; React handles DOM updates |
| Why declarative wins | Predictable, debuggable, composable, maintainable |
UI = f(state) | Same state → always same UI output |
| Debugging | State wrong → bug in update logic. UI wrong but state correct → bug in render |
| Declarative elsewhere | SQL (SELECT), CSS (rules), HTML (structure) |
| Imperative in React | Still needed for: focus, scroll, measurements, third-party DOM libs |
| Key escape hatch | useRef + useEffect for imperative DOM access |
2.1.c — Single Page Applications
| Concept | Key Point |
|---|
| SPA definition | One HTML page; JavaScript handles all navigation and rendering |
| Traditional MPA | Every navigation → full page reload from server |
| Client-side routing | URL changes via History API; no server request for new pages |
| Initial load | SPA: heavy (JS bundle). MPA: light (just HTML) |
| Subsequent nav | SPA: instant (no reload). MPA: slow (full page fetch) |
| SEO challenge | Search engines may not execute JavaScript to see content |
| Blank page problem | User sees nothing until JS downloads, parses, and executes |
| Solutions | SSR (Next.js), SSG, code splitting, prerendering |
| Best for | Interactive apps (dashboards, social, e-commerce) |
| Not ideal for | Content-heavy sites where SEO is critical (without SSR) |
2.1.d — Real DOM vs Virtual DOM
| Concept | Key Point |
|---|
| Real DOM | Browser's actual element tree — heavy objects, triggers reflow/repaint |
| Virtual DOM | Lightweight JS objects mirroring DOM structure |
| Why real DOM is slow | Mutations trigger: style recalc → layout → paint → composite |
| React's process | New VDOM → diff with old VDOM → minimal real DOM patches |
| Reconciliation | React's diffing algorithm comparing old and new virtual trees |
| Batching | Multiple state updates combined into single DOM update |
| Keys in lists | Help React identify which items changed/moved/were removed |
| VDOM overhead | Adds memory + CPU cost; not faster than hand-optimized DOM |
| VDOM benefit | Consistently good performance without manual optimization |
| Alternatives | Svelte (compile-time), SolidJS (fine-grained reactivity) — no VDOM |
2.1.e — Setting Up React with Vite
| Concept | Key Point |
|---|
| Vite | Fast build tool using native ES modules for dev server |
| Why not CRA | CRA is deprecated, slow (Webpack bundles everything upfront) |
| Create project | npm create vite@latest my-app -- --template react |
| Start dev server | cd my-app && npm install && npm run dev |
| Default port | http://localhost:5173 |
| HMR | Hot Module Replacement — updates module without full reload |
vite.config.js | Configure plugins, port, proxy, aliases |
| Production build | npm run build → outputs to dist/ folder |
| Preview build | npm run preview → serves production build locally |
| Dependencies | react, react-dom in deps; vite, @vitejs/plugin-react in devDeps |
2.1.f — Project Structure Breakdown
| File/Folder | Purpose |
|---|
index.html | Entry HTML file (at root in Vite, not in public/) |
src/main.jsx | JavaScript entry — mounts React app to DOM |
src/App.jsx | Root 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.json | Project metadata, scripts, dependencies |
vite.config.js | Vite 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
| Rule | Example |
|---|
| Single root element | Wrap in <div> or <>...</> (Fragment) |
className not class | <div className="box"> |
htmlFor not for | <label htmlFor="email"> |
| camelCase attributes | onClick, tabIndex, autoFocus |
| Style as object | style={{ 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 JSX | Use ternary: {isOn ? 'Yes' : 'No'} |
| Conditional render | {show && <Modal />} |
| List render | {items.map(item => <li key={item.id}>{item.name}</li>)} |
| JSX compiles to | React.createElement(type, props, ...children) |
| Boolean/null/undefined | Not rendered — {false}, {null} produce nothing |
2.1.h — Component-Based Architecture
| Concept | Key Point |
|---|
| Component | Independent, reusable UI function returning JSX |
| Component tree | Hierarchical parent-child structure; App is root |
| Data flow | Props down (parent→child), callbacks up (child→parent) |
| Presentational | Renders UI from props, no data fetching, highly reusable |
| Container | Manages state/data, passes to presentational children |
| Modern pattern | Custom hooks replace container components |
| When to split | >100 lines, multiple responsibilities, reuse opportunity |
| Single responsibility | One component = one job |
| Composition > inheritance | Wrap/configure components, don't extend classes |
children prop | JSX between open/close tags becomes children |
| Compound components | Related components sharing implicit state (Tabs + TabPanel) |
| File organization | Type-based (small), Feature-based (medium+), Atomic (design systems) |
| Naming | PascalCase always: ProductCard, UserAvatar |
| Prop drilling | Passing props through many layers → use Context to solve |
| Anti-patterns | God components, prop explosion, premature abstraction |
| Reusability spectrum | Hardcoded → Configurable → Flexible → Render props → Headless |
Core Formulas & Patterns
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
{isLoggedIn ? <Dashboard /> : <LoginPage />}
{error && <ErrorMessage text={error} />}
{items.map(item => <Card key={item.id} data={item} />)}
<Card><p>Any content here</p></Card>
<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.