⚛ Complete Curriculum

Learn React
in 10 Days

A structured, hands-on journey from zero to building real React apps. Every topic explained with examples, use-cases, and daily tasks.

10Days
40+Topics
30+Examples
25+Tasks
Day 01

Setup, JSX & The React Mental Model

Getting your environment ready and understanding how React thinks

🧠 What is React? Concept

React is a JavaScript library built by Meta for creating user interfaces. Instead of manually updating the DOM (the page), you describe what your UI should look like, and React figures out the how to update it efficiently.

Key idea: React uses a Virtual DOM — a lightweight copy of the real DOM. When data changes, React compares old vs new virtual DOM and only updates the parts that changed. This makes it blazing fast.
📍 Use React when

Building dynamic UIs, single-page apps, dashboards, social feeds, or any interface that changes based on user actions or data.

🚫 Avoid when

Building a simple static webpage with no interactivity — plain HTML/CSS is faster to write and load.

⚙️ Project Setup with Vite Core

The fastest way to start a React project today is with Vite. It replaces the older Create React App and is significantly faster.

bash
# Step 1 — Create the project
npm create vite@latest my-app -- --template react

# Step 2 — Navigate in
cd my-app

# Step 3 — Install dependencies
npm install

# Step 4 — Start development server
npm run dev
structure
my-app/
├── public/          # static files
├── src/
│   ├── App.jsx      # main component
│   ├── main.jsx     # entry point
│   └── index.css    # global styles
├── index.html
└── package.json
📝 JSX — JavaScript + HTML Core

JSX lets you write HTML-like syntax inside JavaScript. It's not real HTML — Babel compiles it into React.createElement() calls behind the scenes.

Why JSX? It makes your component's structure visual and readable. You can see exactly what the UI looks like just by reading the code.
  • Every component must return one parent element (wrap in <></> if needed)
  • Use className instead of class
  • Use htmlFor instead of for
  • All tags must be closed: <img />, <br />
  • JavaScript expressions go inside {'{}'}
jsx
const name = "Shifat";
const isLoggedIn = true;

function App() {
  return (
    <div className="container">
      <h1>Hello, {name}!</h1>
      <p>
        {isLoggedIn ? "Welcome back 👋" : "Please log in"}
      </p>
      <p>2 + 2 = {2 + 2}</p>
    </div>
  );
}
Note: Curly braces {} are your "escape hatch" from JSX back into JavaScript. Put any JS expression inside them — variables, math, ternary operators, function calls.

Day 1 Tasks

Practice Time
01

Create a Profile Card

Build a JSX component that shows your name, role, and a short bio. Use at least 3 JSX rules.

Easy
02

Dynamic Greeting

Create a variable with current hour and display "Good Morning", "Good Afternoon", or "Good Evening" conditionally in JSX.

Medium
03

Math in JSX

Display a simple "calculator result" page showing 5 different math operations rendered in JSX.

Easy
Day 02

Components — Building Blocks of React

How to create, nest, and organize reusable UI pieces

🧩 Functional Components Core

A component is just a JavaScript function that returns JSX. React components must start with a capital letter to distinguish them from regular HTML tags.

jsx
// Button.jsx
function Button() {
  return <button>Click me!</button>;
}

export default Button;

// Arrow function style (same thing)
const Button = () => <button>Click me!</button>;
export default Button;
jsx
// App.jsx
import Button from './Button';
import Header from './Header';

function App() {
  return (
    <div>
      <Header />        // self-closing = no children
      <Button></Button> // or with closing tag
    </div>
  );
}
Rule of thumb: One component = one file. Name the file the same as the component (e.g., Button.jsx exports Button). This keeps your code organised.
🗂️ Component Composition Concept

Big UIs are built by composing small components together — like LEGO bricks. This makes code reusable, testable, and maintainable.

jsx
function Avatar() {
  return <img src="/avatar.png" className="avatar" />;
}

function UserName() {
  return <h2>Shifat</h2>;
}

function UserCard() {
  return (
    <div className="card">
      <Avatar />    // reuse!
      <UserName />  // reuse!
    </div>
  );
}
✅ Good split

Header, Footer, Button, Card, Modal, Sidebar — each distinct UI part deserves its own component.

⚠️ Over-splitting

Don't split too early. If a piece of UI is only used once and is 3 lines, keep it in the parent.

Day 2 Tasks

Practice Time
01

Build a Navbar Component

Create a Navbar with Logo, Nav Links (Home, About, Contact), and a CTA Button as separate components.

Easy
02

Portfolio Layout

Create Header, HeroSection, ProjectCard, and Footer components. Compose them in App.jsx.

Medium
Day 03

Props — Passing Data to Components

Make components dynamic by feeding them data from outside

📦 Props Basics Core

Props (short for properties) are how you pass data from a parent component to a child component. Think of them like function arguments for your components.

jsx
// Parent passes props like HTML attributes
function App() {
  return (
    <div>
      <Greeting name="Shifat" age={22} />
      <Greeting name="Alex" age={25} />
    </div>
  );
}

// Child receives props as an object
function Greeting(props) {
  return (
    <p>
      Hello, {props.name}! You are {props.age} years old.
    </p>
  );
}

// Better: destructure props directly
function Greeting({ name, age }) {
  return <p>Hello, {name}! You are {age}.</p>;
}
Props are read-only! Never modify props inside a child component. If you need to change data, use State (Day 4).
🎭 Default Props & Children Core

You can give props default values in case the parent doesn't pass them. The special children prop lets you pass JSX content between component tags.

jsx
// Default props with destructuring
function Button({ label = "Click me", color = "blue" }) {
  return (
    <button style={{ background: color }}>
      {label}
    </button>
  );
}

// children prop — pass JSX between tags
function Card({ children, title }) {
  return (
    <div className="card">
      <h3>{title}</h3>
      {children}  // renders whatever's between <Card>...</Card>
    </div>
  );
}

// Usage
<Card title="My Project">
  <p>This is card content!</p>
  <Button />
</Card>

Day 3 Tasks

Practice Time
01

Product Card Component

Create a ProductCard that accepts name, price, description, and image as props. Render 3 different products.

Easy
02

Reusable Alert Component

Build an Alert component with type prop (success/error/warning) that changes its color and icon accordingly.

Medium
03

Layout Wrapper with children

Build a PageLayout component using the children prop that wraps any content with Header and Footer.

Medium
Day 04

State & Events — Making UI Interactive

useState hook, event handlers, and reactivity explained

🔄 useState Hook Hook

useState lets you add reactive data to a component. When state changes, React automatically re-renders the component with the new data.

useState returns: [currentValue, setterFunction]. Call the setter to update state — never mutate the variable directly!
jsx
import { useState } from 'react';

function Counter() {
  // [state, setter] = useState(initialValue)
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        +1
      </button>
      <button onClick={() => setCount(0)}>
        Reset
      </button>
    </div>
  );
}
jsx
const [user, setUser] = useState({
  name: "Shifat",
  age: 22
});

// ❌ Wrong — direct mutation
user.name = "Alex";

// ✅ Correct — spread operator creates new object
setUser({ ...user, name: "Alex" });
🖱️ Event Handling Core

React events work like regular DOM events but are named in camelCase and take a function (not a string). Common events: onClick, onChange, onSubmit, onKeyDown.

jsx
function EventDemo() {
  const [text, setText] = useState("");

  // event object 'e' gives you access to input value
  const handleChange = (e) => {
    setText(e.target.value);
  };

  const handleClick = () => {
    alert(`You typed: ${text}`);
  };

  return (
    <div>
      <input
        value={text}
        onChange={handleChange}
        placeholder="Type something..."
      />
      <button onClick={handleClick}>Alert</button>
      <p>Live: {text}</p>
    </div>
  );
}
Common mistake: Don't call the function — pass it!
onClick={handleClick()} — runs on render
onClick={handleClick} — runs on click

Day 4 Tasks

Practice Time
01

Like Button

Build a like button that toggles between liked/unliked state and changes its color and count.

Easy
02

Color Picker

Create 5 color buttons. Clicking each changes the background color of a preview box using state.

Easy
03

Word Counter

Build a textarea that displays live word count, character count, and warns when over 100 words.

Medium
04

Shopping Cart Counter

Display 3 products, each with +/- buttons. Show total items and total price in a summary bar.

Hard
Day 05

Lists, Keys & Conditional Rendering

Rendering arrays of data and showing/hiding UI based on conditions

📋 Rendering Lists with .map() Core

To render a list of items, use JavaScript's .map() method to transform an array of data into an array of JSX elements.

jsx
const fruits = ["🍎 Apple", "🍌 Banana", "🍊 Orange"];

function FruitList() {
  return (
    <ul>
      {fruits.map((fruit, index) => (
        <li key={index}>{fruit}</li>
      ))}
    </ul>
  );
}

// With objects (more realistic)
const users = [
  { id: 1, name: "Shifat", role: "Developer" },
  { id: 2, name: "Alex", role: "Designer" },
];

function UserList() {
  return (
    <div>
      {users.map((user) => (
        <div key={user.id}>
          <strong>{user.name}</strong> - {user.role}
        </div>
      ))}
    </div>
  );
}
Keys: Each list item needs a unique key prop. React uses it to track which items changed. Use a unique ID from your data — avoid using array index for dynamic lists.
🔀 Conditional Rendering Core

Show or hide elements based on conditions. React has several patterns for this.

jsx
function Dashboard({ isLoggedIn, isAdmin, notifications }) {
  return (
    <div>
      // 1. If/else with early return
      {!isLoggedIn && <p>Please log in.</p>}

      // 2. Ternary operator
      {isAdmin
        ? <AdminPanel />
        : <UserPanel />
      }

      // 3. && short-circuit (show if truthy)
      {notifications.length > 0 && (
        <Badge count={notifications.length} />
      )}
    </div>
  );
}
Gotcha with &&: If notifications.length is 0, React renders 0 on screen! Use notifications.length {'>'} 0 && or convert to boolean: !!notifications.length &&

Day 5 Tasks

Practice Time
01

Todo List

Render a hardcoded array of todos. Each todo shows its text and a "Done" badge if completed.

Easy
02

Filterable Product Grid

Show products filtered by category. Add "All", "Electronics", "Clothing" buttons to filter the list.

Hard
Day 06

useEffect — Side Effects & Data Fetching

Running code after renders, API calls, timers, and cleanups

useEffect Hook Hook

useEffect runs after the component renders. Use it for anything that isn't pure rendering — API calls, timers, subscriptions, DOM manipulation.

The dependency array controls when the effect runs:
[] — run once after first render (like componentDidMount)
[value] — run after first render + every time value changes
• No array — run after every single render (rare, usually a bug)
jsx
import { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // This runs after render, whenever userId changes
    async function fetchUser() {
      const res = await fetch(
        `https://jsonplaceholder.typicode.com/users/${userId}`
      );
      const data = await res.json();
      setUser(data);
      setLoading(false);
    }

    fetchUser();
  }, [userId]); // re-run when userId changes

  if (loading) return <p>Loading...</p>;

  return <h2>{user.name}</h2>;
}
jsx
// Return a function to clean up (timers, subscriptions)
useEffect(() => {
  const timer = setInterval(() => {
    setSeconds(s => s + 1);
  }, 1000);

  return () => clearInterval(timer); // cleanup!
}, []);

Day 6 Tasks

Practice Time
01

Live Clock

Build a clock that updates every second using useEffect + setInterval. Include cleanup.

Easy
02

Fetch & Display Posts

Fetch posts from JSONPlaceholder API. Show a loading spinner while fetching, then display the list.

Medium
03

Search with useEffect

Build a search input that fetches results from an API whenever the input value changes (debounce is a bonus).

Hard
Day 07

Forms, Controlled Inputs & Validation

Handling user input, controlled vs uncontrolled components

📝 Controlled Components Core

In React, form inputs are controlled — their value is driven by state, not the DOM. This gives you full control over the data at all times.

jsx
function LoginForm() {
  const [formData, setFormData] = useState({
    email: "",
    password: "",
  });
  const [errors, setErrors] = useState({});

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const validate = () => {
    const newErrors = {};
    if (!formData.email.includes("@"))
      newErrors.email = "Invalid email";
    if (formData.password.length < 6)
      newErrors.password = "Min 6 characters";
    return newErrors;
  };

  const handleSubmit = (e) => {
    e.preventDefault(); // prevent page reload!
    const errs = validate();
    if (Object.keys(errs).length > 0) {
      setErrors(errs);
    } else {
      console.log("Submitted!", formData);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        name="email"
        value={formData.email}
        onChange={handleChange}
      />
      {errors.email && <span>{errors.email}</span>}
      <input
        type="password"
        name="password"
        value={formData.password}
        onChange={handleChange}
      />
      {errors.password && <span>{errors.password}</span>}
      <button type="submit">Login</button>
    </form>
  );
}

Day 7 Tasks

Practice Time
01

Registration Form

Build a sign-up form (name, email, password, confirm password) with validation and error messages.

Medium
02

Dynamic Todo Input

Add an input + button to your Day 5 todo list. Typing and pressing Enter or clicking Add creates a new todo.

Medium
Day 08

React Router — Navigation & Pages

Build multi-page SPAs with client-side routing

🗺️ React Router v6 Core

React Router lets you build multi-page apps without page reloads. The URL changes, but only the component swaps — super fast navigation.

bash
npm install react-router-dom
jsx
// main.jsx — wrap app in BrowserRouter
import { BrowserRouter } from 'react-router-dom';

ReactDOM.createRoot(document.getElementById('root')).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

// App.jsx — define routes
import { Routes, Route, Link } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import UserPage from './pages/UserPage';

function App() {
  return (
    <div>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
      </nav>

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        // Dynamic route with URL param
        <Route path="/user/:id" element={<UserPage />} />
        <Route path="*" element={<h1>404 Not Found</h1>} />
      </Routes>
    </div>
  );
}

// UserPage.jsx — reading URL params
import { useParams } from 'react-router-dom';

function UserPage() {
  const { id } = useParams();
  return <h1>User ID: {id}</h1>;
}

Day 8 Tasks

Practice Time
01

Multi-page Portfolio

Create Home, About, Projects, and Contact pages with a working Navbar using React Router.

Medium
02

Blog with Dynamic Routes

List 5 blog posts. Clicking any opens /blog/:id which fetches and shows that post from JSONPlaceholder.

Hard
Day 09

Context API, useReducer & Custom Hooks

Global state management and building reusable logic

🌐 Context API Advanced

Context solves prop drilling — passing props down through many layers of components just to reach a deeply nested child. With Context, any component can directly access shared state.

jsx
// ThemeContext.jsx
import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext();

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('dark');

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

// Custom hook for easy access
export const useTheme = () => useContext(ThemeContext);

// Any component — no prop drilling!
function ToggleButton() {
  const { theme, setTheme } = useTheme();
  return (
    <button onClick={() =>
      setTheme(theme === 'dark' ? 'light' : 'dark')
    }>
      Switch to {theme === 'dark' ? 'Light' : 'Dark'}
    </button>
  );
}
🪝 Custom Hooks Advanced

Custom hooks are functions starting with use that extract and reuse stateful logic across components. They're one of React's most powerful patterns.

jsx
// hooks/useFetch.js — reusable data fetching
function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch(url)
      .then(r => r.json())
      .then(setData)
      .catch(setError)
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading, error };
}

// Use it anywhere — clean and readable!
function Posts() {
  const { data, loading } = useFetch(
    'https://jsonplaceholder.typicode.com/posts'
  );
  if (loading) return <p>Loading...</p>;
  return <ul>{data.map(p => <li key={p.id}>{p.title}</li>)}</ul>;
}

Day 9 Tasks

Practice Time
01

Dark Mode Context

Implement a global dark/light mode toggle using Context API. All components should respond to the change.

Medium
02

useLocalStorage Hook

Build a custom hook that syncs state to localStorage. Use it for a persistent todo list that survives refresh.

Hard
Day 10

Final Project — Full React App

Bring everything together: a complete Task Manager app

🚀 Project: Task Manager App Project

Build a full-featured Task Manager that combines everything you've learned. This project will demonstrate your React skills to anyone who sees your portfolio.

  • Add, edit, and delete tasks (CRUD)
  • Filter tasks by status: All / Active / Completed
  • Mark tasks as complete with a checkbox
  • Task priority levels (High, Medium, Low) with colors
  • Persist tasks to localStorage with a custom hook
  • Dark/Light mode toggle with Context API
  • Multi-page layout with React Router
structure
src/
├── context/
│   └── ThemeContext.jsx     # dark mode (Day 9)
├── hooks/
│   ├── useLocalStorage.js   # persistence (Day 9)
│   └── useTasks.js          # task logic custom hook
├── pages/
│   ├── Home.jsx             # task list page
│   └── Stats.jsx            # task statistics page
├── components/
│   ├── TaskForm.jsx         # add/edit form (Day 7)
│   ├── TaskList.jsx         # list + filter (Day 5)
│   ├── TaskItem.jsx         # single task card
│   └── Navbar.jsx           # nav with router links (Day 8)
└── App.jsx                  # routes setup
jsx
// hooks/useTasks.js
function useTasks() {
  const [tasks, setTasks] = useLocalStorage('tasks', []);

  const addTask = (text, priority) => {
    setTasks([...tasks, {
      id: Date.now(),
      text,
      priority,
      completed: false
    }]);
  };

  const toggleTask = (id) => {
    setTasks(tasks.map(t =>
      t.id === id ? { ...t, completed: !t.completed } : t
    ));
  };

  const deleteTask = (id) =>
    setTasks(tasks.filter(t => t.id !== id));

  return { tasks, addTask, toggleTask, deleteTask };
}
📈 What's Next After React? Roadmap

Congratulations on completing 10 days! Here's what to learn next to level up.

🔄 State Management

Learn Zustand or Redux Toolkit for complex global state in larger apps.

📡 Data Fetching

Learn TanStack Query (React Query) for caching, loading, and syncing server data.

🎨 Styling

Learn Tailwind CSS for rapid utility-first styling, or styled-components for CSS-in-JS.

⚡ Frameworks

Learn Next.js for SSR, SEO, and full-stack React apps — it's the industry standard.

Day 10 Final Tasks

Capstone
01

Build the Task Manager

Complete all 7 features. Deploy it to Vercel. Add it to your portfolio at shifat.dev.

Hard
02

Write a Post About It

Share what you built and what you learned on X (@Web3DecoderX) or your YouTube channel. Build in public!

Easy
03

Bonus: Add Animations

Integrate Framer Motion to animate task additions, deletions, and page transitions.

Hard