React

Build interactive UIs with components - declarative, efficient, and flexible JavaScript library for web interfaces

TL;DR

One-liner: React is a JavaScript library for building UIs with components - the Lego blocks of web development.

Core Strengths:

  • Component-based - build once, reuse everywhere
  • Virtual DOM - fast updates without touching the real DOM
  • Hooks - elegant state and lifecycle management
  • Massive ecosystem - React Native, Next.js, and thousands of libraries

Core Concepts

Concept 1: Components

Everything in React is a component. A component is just a function that returns JSX (HTML-like syntax in JavaScript).

function Welcome({ name }) {
  return <h1>Hello, {name}!</h1>;
}

// Use it like HTML
<Welcome name="Alice" />

Concept 2: State & Props

Props = data passed from parent to child (read-only) State = data managed inside a component (can change)

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

Concept 3: One-way Data Flow

Data flows down from parent to child through props. Child can’t modify parent’s data directly - it calls callback functions instead.

Quick Start

Create Project

# Using Vite (recommended)
npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev

Project Structure

my-app/
├── src/
│   ├── App.jsx       # Root component
│   ├── main.jsx      # Entry point
│   └── index.css
├── index.html
├── package.json
└── vite.config.js

Minimal Example

// src/App.jsx
import { useState } from 'react';

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

  return (
    <div>
      <h1>Hello React!</h1>
      <button onClick={() => setCount(count + 1)}>
        Count: {count}
      </button>
    </div>
  );
}

export default App;

Run

npm run dev
# Open http://localhost:5173

Gotchas

Component names must be capitalized

// ❌ Wrong - treated as HTML tag
function myButton() { return <button>Hi</button> }

// ✅ Correct
function MyButton() { return <button>Hi</button> }

Don’t call handlers, pass them

// ❌ Wrong - executes immediately on render
<button onClick={handleClick()}>

// ✅ Correct - passes reference
<button onClick={handleClick}>

// ✅ With arguments
<button onClick={() => handleClick(id)}>

State updates are async

const [count, setCount] = useState(0);

function handleClick() {
  setCount(count + 1);
  console.log(count);  // Still 0! State updates on next render
}

// Use function form for multiple updates
setCount(c => c + 1);
setCount(c => c + 1);  // Now correctly adds 2

State is immutable

// ❌ Wrong - mutating state
user.name = 'New Name';
setUser(user);  // React won't re-render!

// ✅ Correct - new object
setUser({ ...user, name: 'New Name' });

// For arrays
setItems([...items, newItem]);  // Add
setItems(items.filter(i => i.id !== id));  // Remove

When to Use

Best for:

  • Single-page applications (SPAs)
  • Complex interactive UIs
  • Teams that want component reusability
  • Projects needing strong ecosystem support

Not ideal for:

  • Simple static sites (use Astro, Hugo)
  • SEO-critical sites without SSR setup (use Next.js instead)
  • Very small projects (vanilla JS might be enough)

Comparison:

FeatureReactVueAngular
Learning curveMediumEasySteep
Size40KB30KB150KB+
StyleLibraryFrameworkFull framework
FlexibilityHighMediumOpinionated

Next Steps

Cheatsheet

PatternCode
Componentfunction Name() { return <div>...</div> }
Propsfunction Card({ title }) { ... }
Stateconst [val, setVal] = useState(initial)
EffectuseEffect(() => { ... }, [deps])
Refconst ref = useRef(null)
Contextconst val = useContext(MyContext)
Conditional{show && <Component />}
List{items.map(i => <Item key={i.id} />)}
EventonClick={fn} / onChange={fn}