Open Documentation

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.

12+
Core Topics
40+
Code Examples
100%
Free & Open

About Kunal

The person behind this documentation.

KG
Kunal Gaikwad
Full Stack Developer · React Enthusiast
Passionate about web technologies, clean code, and sharing knowledge. Currently building and learning — one component at a time.

Setup & Tools

Everything you need before writing your first component.

💡 Prerequisite
Make sure you have Node.js (v18+) and npm installed before proceeding.

Create a new React project

terminal
# Create project with Vite (recommended)
npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev
✅ Tip from Kunal
Always prefer Vite over Create React App — it's significantly faster and the industry standard in 2025.

Recommended VS Code extensions

  1. ES7+ React Snippets — Type rafce and get a full component instantly.
  2. Prettier — Auto-format on save. Set formatOnSave: true in settings.
  3. GitLens — See who changed what and when. Essential for teams.
  4. 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

Greeting.jsx
// 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

App.jsx
import Greeting from './Greeting'

function App() {
  return (
    <div>
      <Greeting name="Kunal" />
      <Greeting name="World" />
    </div>
  )
}
⚠️ Remember
Props flow one-way — from parent to child. Never mutate props inside a component.

Hooks Deep Dive

Hooks are the most powerful feature in modern React. Master them.

useState — managing local state

Counter.jsx
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

DataFetch.jsx
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

HookPurposeWhen to use
useStateLocal component stateUI toggles, form inputs, counters
useEffectSide effectsAPI calls, subscriptions, timers
useContextConsume contextTheme, auth, language
useRefMutable ref / DOM accessFocus, animations, previous value
useMemoMemoize valueExpensive calculations
useCallbackMemoize functionPrevent child re-renders
useReducerComplex state logicMultiple related state values

State Management

Choosing the right tool for the right scale.

Zustand — minimal example

store.js
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.

main.jsx
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.

OptimizedList.jsx
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.

Projects

Build to learn — these project ideas are sorted by complexity.

  1. Todo App — useState, list rendering, conditional UI. The classic starting point.
  2. Weather App — useEffect, API calls, loading/error states, search input.
  3. Notes App with Local Storage — useReducer, custom hooks, persistence layer.
  4. E-commerce Cart — Zustand for cart state, routing, product pages.
  5. Full Stack Blog — React + Node + MongoDB. Auth, CRUD, deployment.

Cheat Sheet

Quick reference — bookmark this.

react-cheatsheet.jsx
/* ── 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