Learn React with
Kunal Gaikwad
A comprehensive, hands-on documentation covering React fundamentals to advanced patterns — written by Kunal Gaikwad for developers who want to build real things.
About Kunal
The person behind this documentation.
Setup & Tools
Everything you need before writing your first component.
Create a new React project
# Create project with Vite (recommended) npm create vite@latest my-app -- --template react cd my-app npm install npm run dev
Recommended VS Code extensions
- ES7+ React Snippets — Type
rafceand get a full component instantly. - Prettier — Auto-format on save. Set
formatOnSave: truein settings. - GitLens — See who changed what and when. Essential for teams.
- React Developer Tools — Browser extension to inspect component trees and state.
React Fundamentals
The building blocks — understand these deeply and everything else becomes easy.
Your first component
// A simple functional component function Greeting({ name }) { return ( <div className="greeting"> <h1>Hello, {name}!</h1> <p>Welcome to React by Kunal.</p> </div> ) } export default Greeting
Props — passing data down
import Greeting from './Greeting' function App() { return ( <div> <Greeting name="Kunal" /> <Greeting name="World" /> </div> ) }
Hooks Deep Dive
Hooks are the most powerful feature in modern React. Master them.
useState — managing local state
import { useState } from 'react' function Counter() { const [count, setCount] = useState(0) return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}> Increment </button> </div> ) }
useEffect — side effects
import { useState, useEffect } from 'react' function DataFetch() { const [data, setData] = useState(null) useEffect(() => { // Runs after every render (empty array = once) fetch('https://api.example.com/data') .then(res => res.json()) .then(json => setData(json)) }, []) // ← dependency array if (!data) return <p>Loading...</p> return <pre>{JSON.stringify(data, null, 2)}</pre> }
All Hooks at a glance
| Hook | Purpose | When to use |
|---|---|---|
| useState | Local component state | UI toggles, form inputs, counters |
| useEffect | Side effects | API calls, subscriptions, timers |
| useContext | Consume context | Theme, auth, language |
| useRef | Mutable ref / DOM access | Focus, animations, previous value |
| useMemo | Memoize value | Expensive calculations |
| useCallback | Memoize function | Prevent child re-renders |
| useReducer | Complex state logic | Multiple related state values |
State Management
Choosing the right tool for the right scale.
Zustand — minimal example
import { create } from 'zustand' const useStore = create((set) => ({ count: 0, increment: () => set((state) => ({ count: state.count + 1 })), reset: () => set({ count: 0 }), })) // In your component: const { count, increment } = useStore()
Routing
React Router v6 — the standard way to handle navigation.
import { BrowserRouter, Routes, Route } from 'react-router-dom' function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/user/:id" element={<User />} /> <Route path="*" element={<NotFound />} /> </Routes> </BrowserRouter> ) }
Performance
Write fast React apps by avoiding unnecessary renders.
import { memo, useMemo, useCallback } from 'react' // memo — prevents re-render if props unchanged const ListItem = memo(({ item, onClick }) => ( <li onClick={() => onClick(item.id)}>{item.name}</li> )) function ItemList({ items }) { // useMemo — recompute only when `items` changes const sorted = useMemo( () => [...items].sort((a, b) => a.name.localeCompare(b.name)), [items] ) // useCallback — stable function reference const handleClick = useCallback((id) => { console.log('clicked:', id) }, []) return <ul>{sorted.map(item => ( <ListItem key={item.id} item={item} onClick={handleClick} /> ))}</ul> }
Design Patterns
Patterns that separate good React code from great React code.
use.Projects
Build to learn — these project ideas are sorted by complexity.
- Todo App — useState, list rendering, conditional UI. The classic starting point.
- Weather App — useEffect, API calls, loading/error states, search input.
- Notes App with Local Storage — useReducer, custom hooks, persistence layer.
- E-commerce Cart — Zustand for cart state, routing, product pages.
- Full Stack Blog — React + Node + MongoDB. Auth, CRUD, deployment.
Cheat Sheet
Quick reference — bookmark this.
/* ── STATE ── */ const [val, setVal] = useState(initial) const [state, dispatch] = useReducer(reducer, init) /* ── EFFECTS ── */ useEffect(() => { /* every render */ }) useEffect(() => { /* once */ }, []) useEffect(() => { /* on dep change */ }, [dep]) useEffect(() => return cleanup, [dep]) /* ── REFS ── */ const ref = useRef(null) <input ref={ref} /> → ref.current.focus() /* ── CONTEXT ── */ const Ctx = createContext(default) const val = useContext(Ctx) /* ── PERFORMANCE ── */ memo(Component) // skip if props same useMemo(() => expr, [deps]) // cache value useCallback(() => fn, [deps]) // cache function
Useful Links
Resources Kunal recommends for going deeper.