React
Chapter 15: Complete React Capstone Project — Architecture, custom hooks, context, controlled forms, router integration, optimistic updates, and production deployment.
1. Full-Stack React Project Architecture
Congratulations on reaching Chapter 15! In this capstone module, we bring together every single concept learned across the React curriculum into a cohesive, production-ready Task & Engineering Milestone Management Application.
2. Complete Production Capstone Implementation
import React, { useState, useEffect, useContext, createContext } from "react";
// 1. CONTEXT: Application Global State
const TaskContext = createContext(null);
export function TaskProvider({ children }) {
const [tasks, setTasks] = useState(() => {
const saved = localStorage.getItem("app_tasks");
return saved ? JSON.parse(saved) : [];
});
useEffect(() => {
localStorage.setItem("app_tasks", JSON.stringify(tasks));
}, [tasks]);
const addTask = (title, priority) => {
const newTask = { id: Date.now().toString(), title, priority, isCompleted: false };
setTasks(prev => [newTask, ...prev]);
};
const toggleTask = (id) => {
setTasks(prev => prev.map(t => t.id === id ? { ...t, isCompleted: !t.isCompleted } : t));
};
const deleteTask = (id) => {
setTasks(prev => prev.filter(t => t.id !== id));
};
return (
<TaskContext.Provider value={{ tasks, addTask, toggleTask, deleteTask }}>
{children}
</TaskContext.Provider>
);
}
// 2. FORM COMPONENT: Controlled Multi-Input
export function CreateTaskForm() {
const { addTask } = useContext(TaskContext);
const [form, setForm] = useState({ title: "", priority: "Medium" });
const [error, setError] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
if (!form.title.trim()) {
setError("Task title cannot be empty!");
return;
}
addTask(form.title, form.priority);
setForm({ title: "", priority: "Medium" });
setError("");
};
return (
<form onSubmit={handleSubmit} className="task-form">
<input
value={form.title}
onChange={(e) => setForm({ ...form, title: e.target.value })}
placeholder="Enter new engineering task..."
/>
<select value={form.priority} onChange={(e) => setForm({ ...form, priority: e.target.value })}>
<option value="High">High Priority</option>
<option value="Medium">Medium Priority</option>
<option value="Low">Low Priority</option>
</select>
<button type="submit">+ Add Task</button>
{error && <p className="err-msg">{error}</p>}
</form>
);
}
3. Production Build & Deployment Pipeline
🚀 Steps to Deploy a Modern React 18 App (Vite $\rightarrow$ Vercel / Netlify)
1. Run Typechecks & Tests: npm run test
2. Compile Production Build: npm run build (Minifies code, bundles with Rollup, and outputs to dist/).
3. SPA Rewrite Rules: For React Router to work on page refresh, add a _redirects (Netlify: /* /index.html 200) or vercel.json rewrite.
4. Capstone Practice Challenges
Challenge 1: Capstone Dashboard Metrics Calculator
Write a pure statistics function calculateProjectStats(tasksList) that computes total, completed, pending, high-priority pending tasks, and completion percentage string (e.g. "33%").
- Compute
totalcount of all tasks in the list. - Count
completedtasks (whereisCompleted === true) andpendingtasks. - Count
highPrioritypending tasks (wherepriority === 'High' && !isCompleted). - Calculate
progressPercentas a rounded percentage string (e.g."33%", or"0%"if empty).
{ total: 3, completed: 1, pending: 2, highPriority: 1, progressPercent: "33%" }
calculateProjectStats to return an object with metrics. Click Run Code to test your logic.
Challenge 2: Multi-Dimensional Filter Pipeline
Implement a search and filter processor searchAndFilterTasks(tasks, options) supporting completion status (all, active, completed), text search query, and priority.
- Filter by completion status:
'active'(isCompleted is false),'completed'(isCompleted is true), or'all'. - Filter by priority: match specified priority or pass all if
priority === 'all'. - Filter by search query: case-insensitive check if
t.title.toLowerCase().includes(query.toLowerCase()).
[{ id: 2, title: "Build Router", isCompleted: false, priority: "High" }]
Challenge 3: Production Deployment Manifest Generator
Write a function generateDeploymentManifest(appName, version, buildTimestamp) that creates a production SPA deployment configuration with immutable cache headers and single-page routing rewrites.
- Accept
appName,version, and optionalbuildTimestamp(defaulting toDate.now()). - Return an object with
app,version,buildId(formatted as`build_${buildTimestamp}`),environment: 'production', andframework: 'React 18 (Vite Bundler)'. - Include
headers: { 'Cache-Control': 'public, max-age=31536000, immutable' }andrewrites: [{ source: '/(.*)', destination: '/index.html' }].
{ app: "ReactMasteryApp", version: "1.0.0", environment: "production", rewrites: [...] }
generateDeploymentManifest to return the deployment config object. Click Run Code to test.