React Day 1: Auth MFE (Vite + TS + Router + MSW) — End-to-End, Line-by-Line
React Day 1: Auth MFE (Vite + TS + Router + MSW) — End-to-End, Line-by-Line
Beginner-friendly, Windows/PowerShell ready. Each example is independent and copy-pasteable.
Introduction
Why this stack? Vite gives instant feedback (HMR), TypeScript adds safety, React Router models SPA navigation, and MSW lets you develop features without a real backend.
React Fundamentals — 10-minute Primer
- Component: A function that returns UI (JSX). Small, reusable building blocks.
- JSX: HTML-like syntax in TS/JS that compiles to
React.createElement
calls. - State: Component “memory”. Updating it triggers a re-render (e.g.,
useState
). - Props: Inputs from parent → child (like function parameters).
- Events:
onClick
,onChange
etc. call handlers to update state. - Effects:
useEffect
for side-effects (fetching, subscriptions). - React vs DOM: You describe what to render; React updates the DOM efficiently.
- Declarative vs Imperative: Declarative says “show this list”; Imperative says “find UL, append LIs”.
- Routing: Client routes map URLs → components without full page reloads.
- Mocking: MSW intercepts
fetch
so you can build confidently offline.
Prerequisites & Setup (PowerShell)
Prerequisites
- Node.js 18+ (prefer 20)
- Git (optional but recommended)
- VS Code or IntelliJ IDEA (Community)
- Basic terminal/PowerShell comfort
Quick Verify
node -v
npm -v
git --version
Workspace & First Project
# 1) Create workspace
PS C:\mycode\react> mkdir day1; cd day1
# 2) Scaffold Vite + React + TS for ex1
PS C:\mycode\react\day1> npm create vite@latest ex1-basic-template -- --template react-ts
# Tip: Press "No" for extra options if asked.
# 3) Install & run
PS C:\mycode\react\day1\ex1-basic-template> npm install
PS C:\mycode\react\day1\ex1-basic-template> npm run dev
# 4) Open http://localhost:5173
Folder Structure (for all examples in this session)
This structure spans the entire session. Each example lives in its own folder.
day1/
ex1-basic-template/
ex2-hello-component/
ex3-hello-props/
ex4-counter-state/
ex5-compose-components/
ex6-router-setup/
ex7-router-links/
ex8-msw-setup/
ex9-users-fetch/
ex10-users-route/
Architecture: What we are building (with diagram)
A small MFE-like React SPA with pages (Home, About, Users). The Users page fetches from /api/users
, intercepted by MSW to return fake JSON. This gives you reliable, repeatable flows without a real backend.
flowchart LR subgraph Browser["React MFE (Vite+TS)"] A[Components
JSX + State + Props] R[React Router] U[Users Page] C[Counter] end subgraph MockLayer["MSW (Mock Service Worker)"] M[Mock handlers
GET /api/users, POST /api/auth/login] end A --> R R --> U A --> C U -- fetch --> M M -- respond --> U
Before you start the examples
- Copy the previous example into a new folder (keeps each milestone intact).
- Open the new folder and
npm install
if needed. - Replace file contents with the full code blocks below (they’re complete for each file).
- Run
npm run dev
, verify, then move to the next example.
# Pattern for each step (Windows PowerShell)
PS C:\mycode\react\day1> robocopy <prev-example> <next-example> /e
PS C:\mycode\react\day1\<next-example>> npm install
PS C:\mycode\react\day1\<next-example>> npm run dev
10 Examples (ex1 → ex10)
ex1 — Basic Vite + TS Template
Goal: Create a minimal React+TS app with Vite as the baseline.
Setup (PowerShell)
PS C:\mycode\react\day1> npm create vite@latest ex1-basic-template -- --template react-ts
PS C:\mycode\react\day1\ex1-basic-template> npm install
PS C:\mycode\react\day1\ex1-basic-template> npm run dev
Concept & Flow
Vite scaffolds a fast dev server, TypeScript config, and a simple React entry. We’ll use this as our seed.
Files (Full code — copy/paste)
src/main.tsx
// main.tsx — React entry point
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>
)
src/App.tsx
// App.tsx — minimal component returning UI
export default function App() {
return (
<div style={{ padding: 24 }}>
<h1>Hello Vite + React + TS</h1>
<p className="muted">Baseline template</p>
</div>
)
}
Key insights
- Key files:
index.html
,src/main.tsx
,src/App.tsx
- Why TS + Vite: speed + safety while learning
- Quick test: Edit the <h1> and see HMR
Exercises + L1 BDD
- Exercise: Add a styled subtitle.
- L1 BDD: Script asserts dev server responds on 5173 (simple curl).
ex2 — Hello Component
Goal: Create and render a reusable component.
Setup (PowerShell)
PS C:\mycode\react\day1> robocopy ex1-basic-template ex2-hello-component /e
PS C:\mycode\react\day1\ex2-hello-component> npm install
PS C:\mycode\react\day1\ex2-hello-component> npm run dev
Concept & Flow
Components are functions returning JSX. We add <Hello/> and render it from App.
Files (Full code — copy/paste)
src/Hello.tsx
// Hello.tsx — simplest possible component
export default function Hello() {
return <h2>Hello React</h2>
}
src/App.tsx
import Hello from "./Hello"
export default function App() {
return (
<div style={{ padding: 24 }}>
<h1>ex2 — Hello Component</h1>
<Hello />
</div>
)
}
Key insights
- Components = functions returning JSX
- Composition = placing components inside others
Exercises + L1 BDD
- Exercise: Wrap <Hello/> in a card.
- L1 BDD: Assert “Hello React” in HTML.
ex3 — Props
Goal: Pass data from parent to child.
Setup (PowerShell)
PS C:\mycode\react\day1> robocopy ex2-hello-component ex3-hello-props /e
PS C:\mycode\react\day1\ex3-hello-props> npm install
PS C:\mycode\react\day1\ex3-hello-props> npm run dev
Concept & Flow
Props are inputs to a component. We pass name
to <Hello/>.
Files (Full code — copy/paste)
src/Hello.tsx
type HelloProps = { name: string }
export default function Hello({ name }: HelloProps) {
return <h2>Hello {name}</h2>
}
src/App.tsx
import Hello from "./Hello"
export default function App() {
return (
<div style={{ padding: 24 }}>
<h1>ex3 — Props</h1>
<Hello name="Ganesh" />
</div>
)
}
Key insights
- Props make components reusable with different data
- Type props with TS for safety
Exercises + L1 BDD
- Exercise: Add a
greeting
prop with default. - L1 BDD: Table-driven names → greetings.
ex4 — State (useState)
Goal: Manage changing data in a component.
Setup (PowerShell)
PS C:\mycode\react\day1> robocopy ex3-hello-props ex4-counter-state /e
PS C:\mycode\react\day1\ex4-counter-state> npm install
PS C:\mycode\react\day1\ex4-counter-state> npm run dev
Concept & Flow
State is component memory. We build a counter with useState
.
Files (Full code — copy/paste)
src/Counter.tsx
import { useState } from "react"
export default function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(c => c + 1)}>+1</button>
</div>
)
}
src/App.tsx
import Counter from "./Counter"
export default function App() {
return (
<div style={{ padding: 24 }}>
<h1>ex4 — State</h1>
<Counter />
</div>
)
}
Key insights
- Event handlers update state → re-render
- Functional update avoids stale state
Exercises + L1 BDD
- Exercise: Add “-1” and “Reset”.
- L1 BDD: Steps click and assert text.
ex5 — Compose Components
Goal: Use multiple components together.
Setup (PowerShell)
PS C:\mycode\react\day1> robocopy ex4-counter-state ex5-compose-components /e
PS C:\mycode\react\day1\ex5-compose-components> npm install
PS C:\mycode\react\day1\ex5-compose-components> npm run dev
Concept & Flow
Composition builds bigger UIs by combining smaller ones.
Files (Full code — copy/paste)
src/Hello.tsx
export default function Hello({ name = "React" }: { name?: string }) {
return <h2>Hello {name}</h2>
}
src/App.tsx
import Hello from "./Hello"
import Counter from "./Counter"
export default function App() {
return (
<div style={{ padding: 24 }}>
<h1>ex5 — Composition</h1>
<Hello name="Ganesh" />
<Counter />
</div>
)
}
Key insights
- Compose to keep each piece focused
- Props let repeated pieces vary
Exercises + L1 BDD
- Exercise: Add a second Counter with its own label.
- L1 BDD: Two counters update independently.
ex6 — Router Setup
Goal: Switch views by URL using React Router.
Setup (PowerShell)
PS C:\mycode\react\day1> robocopy ex5-compose-components ex6-router-setup /e
PS C:\mycode\react\day1\ex6-router-setup> npm install react-router-dom
PS C:\mycode\react\day1\ex6-router-setup> npm run dev
Concept & Flow
Router picks which component to show based on the URL.
Files (Full code — copy/paste)
src/App.tsx
import { BrowserRouter, Routes, Route } from "react-router-dom"
function Home() { return <h2>Home</h2> }
function About() { return <h2>About</h2> }
export default function App() {
return (
<BrowserRouter>
<div style={{ padding: 24 }}>
<h1>ex6 — Router</h1>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</div>
</BrowserRouter>
)
}
Key insights
<BrowserRouter>
wraps once- Each
Route
maps path → component
Exercises + L1 BDD
- Exercise: Add
/counter
route with <Counter/>. - L1 BDD: Navigate and assert headings.
ex7 — Navigation Links
Goal: Navigate declaratively with <Link>.
Setup (PowerShell)
PS C:\mycode\react\day1> robocopy ex6-router-setup ex7-router-links /e
PS C:\mycode\react\day1\ex7-router-links> npm install
PS C:\mycode\react\day1\ex7-router-links> npm run dev
Concept & Flow
<Link> changes URL without full page reload.
Files (Full code — copy/paste)
src/App.tsx
import { BrowserRouter, Routes, Route, Link } from "react-router-dom"
function Home() { return <h2>Home</h2> }
function About() { return <h2>About</h2> }
export default function App() {
return (
<BrowserRouter>
<div style={{ padding: 24 }}>
<h1>ex7 — Links</h1>
<nav style={{ display:"flex", gap:12 }}>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</div>
</BrowserRouter>
)
}
Key insights
- Declarative nav via
<Link>
- No full reload; state can persist
Exercises + L1 BDD
- Exercise: Add active link style.
- L1 BDD: Click Home→About and assert headings.
ex8 — MSW Setup (Mock API)
Goal: Intercept fetch
and return fake data (no real server).
Setup (PowerShell)
PS C:\mycode\react\day1> robocopy ex7-router-links ex8-msw-setup /e
PS C:\mycode\react\day1\ex8-msw-setup> npm install msw --save-dev
PS C:\mycode\react\day1\ex8-msw-setup> npm run dev
Concept & Flow
MSW registers a service worker in dev; our handlers return JSON for paths like /api/users
.
Files (Full code — copy/paste)
src/mocks/handlers.ts
import { http, HttpResponse } from "msw"
export const handlers = [
http.get("/api/users", () => {
return HttpResponse.json([
{ id: 1, name: "Ada" },
{ id: 2, name: "Linus" }
])
}),
http.post("/api/auth/login", async ({ request }) => {
const body = await request.json()
if (body.username && body.password) {
return HttpResponse.json({ token: "fake-jwt", user: { name: body.username } })
}
return HttpResponse.json({ error: "invalid" }, { status: 400 })
}),
]
src/mocks/browser.ts
import { setupWorker } from "msw/browser"
import { handlers } from "./handlers"
export const worker = setupWorker(...handlers)
src/main.tsx (start worker in dev)
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
async function enableMocking() {
if (import.meta.env.DEV) {
const { worker } = await import('./mocks/browser')
await worker.start()
}
}
enableMocking()
createRoot(document.getElementById('root')!).render(
<StrictMode><App /></StrictMode>
)
Key insights
- Place handlers under
src/mocks/
- Call
worker.start()
before app renders (dev)
Exercises + L1 BDD
- Exercise: Add
GET /api/profile
handler. - L1 BDD: Step hits mocked endpoint and asserts JSON shape.
ex9 — Fetch Users Component
Goal: Load users from /api/users
(intercepted by MSW) and display.
Setup (PowerShell)
PS C:\mycode\react\day1> robocopy ex8-msw-setup ex9-users-fetch /e
PS C:\mycode\react\day1\ex9-users-fetch> npm install
PS C:\mycode\react\day1\ex9-users-fetch> npm run dev
Concept & Flow
useEffect
triggers fetch on mount; state holds results; MSW fulfills the request.
Files (Full code — copy/paste)
src/Users.tsx
import { useEffect, useState } from "react"
type User = { id: number; name: string }
export default function Users() {
const [users, setUsers] = useState<User[]>([])
const [loading, setLoading] = useState(true)
useEffect(() => {
fetch("/api/users")
.then(r => r.json())
.then(data => setUsers(data))
.finally(() => setLoading(false))
}, [])
if (loading) return <p>Loading...</p>
return (
<ul>
{users.map(u => <li key={u.id}>{u.name}</li>)}
</ul>
)
}
src/App.tsx
import Users from "./Users"
export default function App() {
return (
<div style={{ padding: 24 }}>
<h1>ex9 — Users</h1>
<Users />
</div>
)
}
Key insights
useEffect(..., [])
runs once on mount- MSW supplies the data → deterministic dev
Exercises + L1 BDD
- Exercise: Add a skeleton for ~800ms.
- L1 BDD: Names appear in order (Ada, Linus).
ex10 — Integrate Users with Router
Goal: Add /users
route and wire menu → page → fetch (MSW).
Setup (PowerShell)
PS C:\mycode\react\day1> robocopy ex9-users-fetch ex10-users-route /e
PS C:\mycode\react\day1\ex10-users-route> npm install
PS C:\mycode\react\day1\ex10-users-route> npm run dev
Concept & Flow
Full mini-app: Home/About/Users; Users lists data from mocked API.
Files (Full code — copy/paste)
src/App.tsx
import { BrowserRouter, Routes, Route, Link } from "react-router-dom"
import Users from "./Users"
function Home() { return <h2>Home</h2> }
function About() { return <h2>About</h2> }
export default function App() {
return (
<BrowserRouter>
<div style={{ padding: 24 }}>
<h1>ex10 — Users Route</h1>
<nav style={{ display:"flex", gap:12 }}>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/users">Users</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/users" element={<Users />} />
</Routes>
</div>
</BrowserRouter>
)
}
Key insights
- Router ties pages together
- MSW keeps dev productive and offline
Exercises + L1 BDD
- Exercise: Add detail page
/users/:id
with handlerGET /api/users/:id
. - L1 BDD: Navigate list → detail and assert JSON fields.
Comments
Post a Comment