React.js Framework – Complete Notes

React कंपोनेंट्स, हुक्स और स्टेट मैनेजमेंट के साथ डायनामिक UI बनाएं – Detailed notes in English and हिंदी

1. Introduction to React.js – Evolution & Core Concept

English

  1. Problem: Before React, developers built dynamic user interfaces with plain JavaScript and the DOM API. Every data change meant manually finding the right element and updating it (document.getElementById(...).innerHTML = ...). State was scattered across DOM attributes, global variables, and event handlers — nobody knew the "single source of truth". As the app grew, the code became a tangle of event listeners and callbacks: slow to render, hard to debug, and impossible to reuse. There was no reliable way to keep the view automatically in sync with the data.
  2. Definition: React is an open-source JavaScript library created by Jordan Walke at Facebook (Meta) and released in 2013. It builds user interfaces by composing small, isolated, reusable pieces called components. React is declarative — you describe what the UI should look like for a given state, and React figures out how to update the DOM. The mental model is a simple formula: UI = f(state).
  3. Example: Old way vs React way of building a click counter:
    // Old way (plain JavaScript)
    let count = 0;
    btn.onclick = () => { count++; btn.textContent = `Clicked ${count} times`; };
    
    // React way
    import { useState } from 'react';
    function ClickCounter() {
      const [count, setCount] = useState(0);
      return (
        <button onClick={() => setCount(count + 1)}>
          Clicked {count} times
        </button>
      );
    }
    In React you only change the state. React re-renders the component automatically. The view can never drift away from the data.
  4. Types:
    Category Options Description
    By component kind Function components (modern) / Class components (legacy) Function components with Hooks are the current standard.
    By rendering strategy CSR, SSR, SSG, ISR, React Server Components (RSC) CSR renders in the browser; SSR/SSG render on the server for SEO and speed.
    By platform React DOM (web), React Native (mobile), React Three Fiber (3D) Same mental model, different renderers.
  5. Advantages:
    • Declarative code: You write what the UI should be, not the steps to change it. Code is shorter and easier to read.
    • Component reusability: A button, card, or modal written once can be used hundreds of times.
    • Automatic UI syncing: State changes automatically trigger re-renders.
    • Excellent performance: Virtual DOM diffing minimises expensive real DOM operations.
    • Huge ecosystem: React Router, Redux Toolkit, TanStack Query, Next.js, and thousands of libraries.
    • Strong community and jobs market: Massive Stack Overflow presence and hiring demand.
    • Testability: Components are pure functions of props and state.
    • Learn once, write anywhere: Same mental model for web and mobile via React Native.
    • Backed by Meta: Long-term stability and continuous innovation (Hooks, Concurrent mode, Server Components).
  6. Disadvantages:
    • It is only the view layer: You must choose extra libraries for routing, forms, and state.
    • JSX learning curve: Mixing HTML-like syntax with JavaScript confuses beginners at first.
    • Rapid ecosystem churn: Best practices change often (classes → hooks → server components); tutorials go stale.
    • Boilerplate for small apps: A tiny static site needs Vite, npm, and bundlers.
    • SEO and initial load (CSR): Pure client-side React can hurt SEO without SSR/SSG.
    • State management complexity: In large apps, prop drilling and context performance issues appear.
    • Over-rendering risk: Without care, components re-render too often and hurt performance.
    • Not a full framework: No built-in opinion on file structure, so teams can build inconsistent codebases.
  7. Characteristics:
    • Component-based architecture: The UI is a tree of independent, composable components.
    • Declarative programming style: Describe the result, not the procedure.
    • Virtual DOM: An in-memory representation of the real DOM used for fast diffing.
    • Unidirectional data flow: Data moves down via props; events move up via callbacks.
    • JSX: A syntax extension that lets you write markup inside JavaScript.
    • Props and State: Props are read-only inputs; state is mutable internal data.
    • Hooks: Functions like useState and useEffect that add state and side effects to function components.
    • Composition over inheritance: Components are combined, not subclassed.
    • Just JavaScript: Conditions and loops use normal JS.
    • Rich developer tooling: React DevTools, Fast Refresh, and error overlays.
  8. Diagram: Component tree and Virtual DOM flow
                     ┌──────────────────┐
                     │    App (Root)    │
                     └────────┬─────────┘
                              │
              ┌───────────────┴───────────────┐
              │                               │
         ┌────▼─────┐                   ┌─────▼──────┐
         │  Header  │                   │    Main    │
         └────┬─────┘                   └─────┬──────┘
              │                               │
         ┌────▼─────┐              ┌──────────┴──────────┐
         │   Logo   │         ┌────▼────┐          ┌─────▼─────┐
         └──────────┘         │ Counter │          │ TodoList  │
                              └─────────┘          └───────────┘
    
      State / Props change
               │
               ▼
      ┌─────────────────────┐
      │  New Virtual DOM    │
      │  (JS object tree)   │
      └──────────┬──────────┘
                 │  diff / reconcile
      ┌──────────▼──────────┐
      │ Compare with old    │
      │ Virtual DOM         │
      └──────────┬──────────┘
                 │
                 ▼
      ┌─────────────────────┐
      │ Minimal real DOM    │
      │ updates only        │
      └─────────────────────┘
    
      One-way data flow:
       Parent  ──── props (data down) ────►  Child
       Parent  ◄─── callback (events up) ───  Child
  9. Conclusion: React solves a very real problem: keeping a complex, interactive UI in sync with changing data without manual DOM surgery. By introducing components, JSX, a Virtual DOM, and one-way data flow, it makes user interfaces predictable, reusable, and testable. It is a library, not a full framework, which means you get flexibility at the cost of having to make architectural choices yourself. Modern React is built on function components and Hooks, with frameworks like Next.js handling routing, rendering strategies, and server components on top. Learning React is therefore not just learning a library — it is learning a way of thinking about UI as a function of state.
  10. Exercise:
    1. In your own words, explain the difference between declarative and imperative UI programming with one example each.
    2. Create a new React project using npm create vite@latest my-app -- --template react and run the dev server.
    3. Write a Greeting component that accepts a name prop and renders “Hello, <name>!”.
    4. Build a LikeButton component that shows “Likes: 0” and increments on click.
    5. Show “You liked this!” once the count is greater than zero.
    6. Build an App with Header, Greeting, and two independent LikeButtons.
    7. List three problems React does not solve on its own, and name one library for each.

हिंदी (सरल)

  1. समस्या: React से पहले developers plain JavaScript और DOM API से dynamic user interfaces बनाते थे। हर data बदलाव पर सही element ढूँढकर manually update करना पड़ता था (document.getElementById(...).innerHTML = ...)। State DOM attributes, global variables और event handlers में बिखरी रहती थी — किसी को "single source of truth" का पता ही नहीं चलता था। App बड़ा होने पर code event listeners और callbacks का जाल बन जाता था: render धीमा, debug करना मुश्किल, और reuse करना असंभव। View को data के साथ अपने आप sync रखने का कोई भरोसेमंद तरीका नहीं था।
  2. परिभाषा: React एक open-source JavaScript library है, जिसे Facebook (Meta) में Jordan Walke ने बनाया और 2013 में release किया गया। यह user interfaces को छोटे-छोटे, isolated, reusable टुकड़ों से बनाता है जिन्हें components कहते हैं। React declarative है — आप बताते हैं कि UI कैसा दिखना चाहिए, और React खुद तय करता है कि DOM कैसे update करना है। सोचने का सूत्र: UI = f(state)।
  3. उदाहरण: पुराना तरीका बनाम React तरीका:
    // पुराना तरीका (plain JavaScript)
    let count = 0;
    btn.onclick = () => { count++; btn.textContent = `Clicked ${count} times`; };
    
    // React तरीका
    import { useState } from 'react';
    function ClickCounter() {
      const [count, setCount] = useState(0);
      return (
        <button onClick={() => setCount(count + 1)}>
          Clicked {count} times
        </button>
      );
    }
    React में आप सिर्फ state बदलते हैं। React component को अपने आप दोबारा render करता है। View और data कभी अलग नहीं हो सकते।
  4. प्रकार:
    श्रेणी विकल्प विवरण
    Component के प्रकार से Function components (आधुनिक) / Class components (पुराने) Hooks वाले function components आज standard हैं।
    Rendering strategy से CSR, SSR, SSG, ISR, React Server Components (RSC) CSR browser में render होता है; SSR/SSG server पर — SEO और speed के लिए।
    Platform से React DOM (web), React Native (mobile), React Three Fiber (3D) वही सोच, अलग renderers।
  5. लाभ:
    • Declarative code: आप लिखते हैं UI कैसा दिखेगा, बदलाव के steps नहीं। Code छोटा और पढ़ने में आसान।
    • Component reusability: एक बार लिखा button, card या modal सैकड़ों जगह use हो सकता है।
    • UI अपने आप sync: State बदलते ही re-render अपने आप होता है।
    • बेहतर performance: Virtual DOM diffing से महँग DOM operations कम हो जाते हैं।
    • बहुत बड़ा ecosystem: React Router, Redux Toolkit, TanStack Query, Next.js और हज़ारों libraries।
    • मज़बूत community और jobs: Stack Overflow पर बहुत मदद और hiring demand।
    • Testability: Components props और state के pure functions होते हैं।
    • एक बार सीखो, कहीं भी लिखो: React Native से वही सोच mobile पर भी।
    • Meta का support: Long-term stability और लगातार नए features।
  6. नुकसान:
    • सिर्फ view layer: Routing, forms और state के लिए अलग libraries चुननी पड़ती हैं।
    • JSX की learning curve: HTML जैसा syntax JavaScript के बीच लिखना शुरू में confusing।
    • Ecosystem बहुत तेज़ी से बदलता है: Best practices बदलते रहते हैं (classes → hooks → server components), पुराने tutorials stale हो जाते हैं।
    • छोटे apps में boilerplate: छोटी static site के लिए भी Vite, npm और bundlers चाहिए।
    • SEO और initial load (CSR): सिर्फ client-side React से SEO और पहला paint खराब हो सकता है।
    • State management की जटिलता: बड़े apps में prop drilling और context performance समस्याएँ।
    • अत्यधिक re-render: ध्यान न दें तो components बहुत बार render होते हैं।
    • पूरा framework नहीं: File structure पर कोई सख्त नियम नहीं।
  7. विशेषताएँ:
    • Component-based architecture: UI independent, composable components का tree है।
    • Declarative style: नतीजा बताइए, तरीका नहीं।
    • Virtual DOM: असली DOM की memory में बनी copy, fast diffing के लिए।
    • Unidirectional data flow: Data props से नीचे, events callbacks से ऊपर।
    • JSX: JavaScript के अंदर markup लिखने देने वाला syntax extension।
    • Props और State: Props read-only inputs, State mutable internal data।
    • Hooks: useState, useEffect जैसे functions।
    • Composition over inheritance: Components जोड़े जाते हैं, subclass नहीं।
    • सिर्फ JavaScript: कोई नई templating language नहीं।
    • अच्छी developer tooling: React DevTools, Fast Refresh, error overlays।
  8. आरेख: Component tree और Virtual DOM flow
                     ┌──────────────────┐
                     │    App (Root)    │
                     └────────┬─────────┘
                              │
              ┌───────────────┴───────────────┐
              │                               │
         ┌────▼─────┐                   ┌─────▼──────┐
         │  Header  │                   │    Main    │
         └────┬─────┘                   └─────┬──────┘
              │                               │
         ┌────▼─────┐              ┌──────────┴──────────┐
         │   Logo   │         ┌────▼────┐          ┌─────▼─────┐
         └──────────┘         │ Counter │          │ TodoList  │
                              └─────────┘          └───────────┘
    
      State / Props बदला
               │
               ▼
      ┌─────────────────────┐
      │  नया Virtual DOM    │
      └──────────┬──────────┘
                 │  diff / reconcile
      ┌──────────▼──────────┐
      │  पुराने Virtual DOM │
      │  से तुलना           │
      └──────────┬──────────┘
                 │
                 ▼
      ┌─────────────────────┐
      │ सिर्फ ज़रूरी real    │
      │ DOM updates         │
      └─────────────────────┘
    
      एक दिशा में data flow:
       Parent  ──── props (data नीचे) ────►  Child
       Parent  ◄─── callback (event ऊपर) ───  Child
  9. निष्कर्ष: React एक असली समस्या हल करता है: बिना DOM को हाथ से छुए, बदलते data के साथ complex और interactive UI को sync में रखना। Components, JSX, Virtual DOM और one-way data flow की मदद से यह user interfaces को predictable, reusable और testable बना देता है। यह पूरा framework नहीं, बल्कि एक library है — इसलिए flexibility मिलती है, पर architecture के फैसले खुद लेने पड़ते हैं। आधुनिक React function components और Hooks पर टिका है, और Next.js जैसे frameworks routing, rendering strategies और server components संभालते हैं। इसलिए React सीखना सिर्फ एक library सीखना नहीं, बल्कि UI को state का function मानकर सोचना सीखना है।
  10. अभ्यास:
    1. अपने शब्दों में declarative और imperative UI programming का फर्क समझाइए, दोनों का एक-एक उदाहरण दीजिए।
    2. npm create vite@latest my-app -- --template react से नया React project बनाइए।
    3. एक Greeting component लिखिए जो name prop लेता है।
    4. एक LikeButton बनाइए जो click पर count बढ़ाता है।
    5. count > 0 होने पर “You liked this!” दिखाइए।
    6. एक App बनाइए जिसमें Header, Greeting और दो अलग LikeButton हों।
    7. तीन ऐसी समस्याएँ लिखिए जो React अकेले हल नहीं करता, और हर एक के लिए एक library का नाम दीजिए।

2. React Components – Props, Children & Composition

English

  1. Problem: In plain HTML you copy-paste the same markup block repeatedly. A card, a button, or a modal written 50 times causes duplicated logic, inconsistency, and bugs. There is no reusability, and changing one thing means editing 50 places. Components solve this by letting you define UI once and reuse it everywhere.
  2. Definition: A component is a reusable, independent piece of UI. Function components are JavaScript functions that return JSX. Props are read-only inputs passed from parent to child. Children is a special prop that allows composition — wrapping other elements inside a component. Components are the building blocks of every React app.
  3. Example: A Greeting component used multiple times plus a composable Card:
    // Simple component with a prop
    function Greeting({ name }) {
      return <h1>Hello, {name}!</h1>;
    }
    
    // Component using children for composition
    function Card({ title, children }) {
      return (
        <div className="card">
          <h3>{title}</h3>
          <div className="card-body">{children}</div>
        </div>
      );
    }
    
    // Using both
    function App() {
      return (
        <div>
          <Greeting name="Amit" />
          <Greeting name="Priya" />
    
          <Card title="Welcome">
            <p>This is inside the Card.</p>
            <button>Click me</button>
          </Card>
        </div>
      );
    }
  4. Types:
    Type Description Example
    Function components Plain JS functions returning JSX. Modern standard. function Card() { return <div />; }
    Class components ES6 classes extending React.Component. Legacy. class Card extends React.Component
    Container / Presentational Container handles logic; presentational handles UI. <UserContainer /> vs <UserView />
    Compound components Parent + children share implicit state as one API. <Tabs><Tabs.Tab /></Tabs>
    HOC (Higher-Order Component) Function that takes a component and returns a wrapped one. withAuth(Dashboard)
  5. Advantages:
    • Reusability: Write once, use hundreds of times. Reduces code duplication.
    • Composition: Build complex UIs from simple pieces using children.
    • Testability: Each component can be tested in isolation.
    • Clear data flow: Data flows down through props; events bubble up via callbacks.
    • Team collaboration: One team can own one component end-to-end.
    • Separation of concerns: Business logic can live in container components; presentation in presentational ones.
  6. Disadvantages:
    • Prop drilling: In deep trees, passing props through many levels becomes tedious.
    • Over-splitting: Too many tiny components make many files and hurt readability.
    • Naming confusion: Poorly named components blur responsibility.
    • Re-render cost: If props change frequently, components re-render often.
    • JSX learning curve: New developers may find JSX syntax unusual at first.
  7. Characteristics:
    • Props are immutable: A child must never modify its props.
    • Children is a special prop: Used for nesting other JSX.
    • Single root element: Components return one root element, or a Fragment (<>...</>).
    • Names must be Capitalised: React treats lowercase tags as HTML elements.
    • Composition over inheritance: Prefer passing elements and functions over subclassing.
    • Pure rendering: Given the same props, a component should render the same output.
  8. Diagram: Parent → child props flow and composition
       Parent  ──── props (data down) ────►  Child
       Parent  ◄─── callback (events up) ───  Child
    
    Component Tree:
    
    <App>
     ├─ <Header title="My Site" />
     ├─ <Card title="Welcome">
     │    ├─ <p>Hello World</p>
     │    └─ <Button label="OK" onClick={handleOk} />
     └─ <Footer year={2025} />
    
    Composition:
      <Card>
        └─ children = whatever you put inside
      </Card>
  9. Conclusion: Components are the heart of React. Mastering props, children, and composition is essential before moving to state and hooks. Every complex app is just a tree of well-designed components passing props down and events up. Favour composition over inheritance and keep each component focused on one concern. Consistent naming and small, predictable components make the codebase pleasant to work with as it grows.
  10. Exercise:
    1. Build a Card component that accepts title and children.
    2. Build a Button component with label and onClick props.
    3. Create a UserList that receives an array of users via props.
    4. Explain why props are read-only.
    5. Convert a repeated HTML block into a reusable component.

हिंदी (सरल)

  1. समस्या: Plain HTML में एक ही markup block बार-बार copy-paste करना पड़ता है। एक card, button या modal अगर 50 बार लिखा जाए तो logic duplicate होता है, inconsistency बढ़ती है और bugs आते हैं। Reusability नहीं होती, और एक चीज़ बदलने के लिए 50 जगह edit करनी पड़ती है। Components इस समस्या को हल करते हैं — UI एक बार define करें और हर जगह reuse करें।
  2. परिभाषा: Component UI का एक reusable, independent टुकड़ा है। Function components JavaScript functions हैं जो JSX return करते हैं। Props parent से child को भेजे जाने वाले read-only inputs हैं। Children एक special prop है जो composition की अनुमति देती है — किसी component के अंदर दूसरे elements wrap करना। Components हर React app के निर्माण खंड हैं।
  3. उदाहरण: एक Greeting component और children वाला composable Card:
    // Prop के साथ साधारण component
    function Greeting({ name }) {
      return <h1>नमस्ते, {name}!</h1>;
    }
    
    // Composition के लिए children वाला component
    function Card({ title, children }) {
      return (
        <div className="card">
          <h3>{title}</h3>
          <div className="card-body">{children}</div>
        </div>
      );
    }
    
    // दोनों का उपयोग
    function App() {
      return (
        <div>
          <Greeting name="अमित" />
          <Greeting name="प्रिया" />
    
          <Card title="स्वागत">
            <p>यह Card के अंदर है।</p>
            <button>क्लिक कीजिए</button>
          </Card>
        </div>
      );
    }
  4. प्रकार:
    प्रकार विवरण उदाहरण
    Function components साधारण JS functions जो JSX return करते हैं। आधुनिक standard। function Card() { return <div />; }
    Class components ES6 classes जो React.Component extend करती हैं। पुराने। class Card extends React.Component
    Container / Presentational Container logic संभालता है; presentational UI। <UserContainer /> बनाम <UserView />
    Compound components Parent + children मिलकर एक API की तरह काम करते हैं। <Tabs><Tabs.Tab /></Tabs>
    HOC (Higher-Order Component) Function जो component लेकर wrapped component देता है। withAuth(Dashboard)
  5. लाभ:
    • Reusability: एक बार लिखें, सैकड़ों बार use करें। Code दोहराव कम।
    • Composition: children से छोटे टुकड़ों से complex UI बनाएँ।
    • Testability: हर component को अलग test कर सकते हैं।
    • साफ data flow: Data props से नीचे, events callbacks से ऊपर।
    • Team collaboration: एक team एक component end-to-end संभाल सकती है।
    • Separation of concerns: Business logic container में, presentation presentational में।
  6. नुकसान:
    • Prop drilling: गहरे trees में props कई levels से भेजना tedious।
    • Over-splitting: बहुत छोटे components से कई files बन जाती हैं।
    • Naming confusion: खराब नाम responsibility धुँधली कर देते हैं।
    • Re-render cost: Props बार-बार बदलें तो re-render cost।
    • JSX learning curve: नए developers को JSX शुरू में अजीब लगता है।
  7. विशेषताएँ:
    • Props immutable: Child अपने props कभी modify न करे।
    • Children special prop: दूसरे JSX nesting के लिए।
    • Single root element: एक root element या Fragment (<>...</>)।
    • नाम Capitalised: lowercase tags React HTML elements मानता है।
    • Composition over inheritance: Subclassing से बेहतर elements/functions pass करना।
    • Pure rendering: वही props → वही output।
  8. आरेख: Parent → child props flow और composition
       Parent  ──── props (data नीचे) ────►  Child
       Parent  ◄─── callback (event ऊपर) ───  Child
    
    Component Tree:
    
    <App>
     ├─ <Header title="मेरी साइट" />
     ├─ <Card title="स्वागत">
     │    ├─ <p>नमस्ते दुनिया</p>
     │    └─ <Button label="ठीक" onClick={handleOk} />
     └─ <Footer year={2025} />
    
    Composition:
      <Card>
        └─ children = जो भी अंदर रखें
      </Card>
  9. निष्कर्ष: Components React का दिल हैं। State और hooks पर जाने से पहले props, children और composition में महारत हासिल करना ज़रूरी है। हर complex app असल में अच्छी तरह डिज़ाइन किए गए components का tree है जो props नीचे और events ऊपर भेजता है। Composition over inheritance को अपनाएँ और हर component को एक concern पर केंद्रित रखें। Consistent naming और छोटे, predictable components codebase को बढ़ते हुए भी सुखद बनाए रखते हैं।
  10. अभ्यास:
    1. एक Card component बनाइए जो title और children लेता है।
    2. एक Button component बनाइए जिसमें label और onClick props हों।
    3. एक UserList बनाइए जो props से users का array लेता है।
    4. समझाइए कि props read-only क्यों होते हैं।
    5. एक repeated HTML block को reusable component में बदलिए।

3. State in React – useState & Immutable Updates

English

  1. Problem: Components need to remember data that changes over time — a counter, a form value, a toggle, an array of items. Without state, every change would require manual DOM updates, and variables would reset on every render. There needed to be a clean way to store and update data that the UI depends on, and to have React automatically re-render when it changes.
  2. Definition: State is mutable data owned by a component. Changing state triggers a re-render. In function components, local state is created with the useState hook, which returns a pair: the current value and a setter function. State updates are asynchronous and must be immutable — you never modify the existing value; you create a new one.
  3. Example: A counter with useState plus immutable array update:
    import { useState } from 'react';
    
    function Counter() {
      const [count, setCount] = useState(0);
      const [items, setItems] = useState([]);
    
      const addItem = () => {
        // Correct: create a NEW array
        setItems(prev => [...prev, `Item ${prev.length + 1}`]);
      };
    
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={() => setCount(c => c + 1)}>+1</button>
          <button onClick={() => setCount(0)}>Reset</button>
    
          <button onClick={addItem}>Add item</button>
          <ul>
            {items.map((item, i) => <li key={i}>{item}</li>)}
          </ul>
        </div>
      );
    }
  4. Types:
    Type Description Example
    Local state Owned by one component, e.g., form input value. const [name, setName] = useState('')
    Lifted state Moved to a common parent so siblings can share it. <Parent value={x} setValue={setX} />
    Derived state Computed from props or other state — do not store if derivable. const total = items.length
    Global state Shared across many components (Context, Redux, Zustand). useStore()
    Server state Data from APIs with caching and syncing (TanStack Query). useQuery(...)
  5. Advantages:
    • UI stays in sync: State changes automatically re-render the component.
    • Simple API: useState is easy to learn and use.
    • Colocation: State lives close to where it's used.
    • Predictable updates: Updates go through the setter, making state changes traceable.
    • Composable: Multiple useState calls can coexist cleanly.
  6. Disadvantages:
    • Async updates: Reading state right after setting gives the old value.
    • Mutating directly does nothing: Must always create new objects or arrays.
    • Prop drilling: Lifting state too high causes verbose prop passing.
    • Too much state: Many pieces of state in one component make it complex.
    • Easy to store derived values: Which causes bugs when they drift out of sync.
  7. Characteristics:
    • Each useState returns [value, setter].
    • Setter can take a value or an updater function: setCount(c => c + 1).
    • Updates are batched: Multiple setState calls in one event are combined for performance.
    • Immutable: Never mutate objects/arrays — create new ones.
    • Re-renders trigger: When the value changes by reference or primitive equality.
  8. Diagram: State update triggers re-render
    setCount(count + 1)
            │
            ▼
      State updated
            │
            ▼
      Component re-renders
            │
            ▼
      New JSX → diff → DOM updated
    
    Immutable update pattern:
    
      // Wrong
      items.push(newItem);      // no re-render
      setItems(items);
    
      // Correct
      setItems([...items, newItem]);
      // or
      setItems(prev => [...prev, newItem]);
  9. Conclusion: State is what makes React components interactive. Understanding immutable updates and the asynchronous nature of setState is critical to avoiding subtle bugs. Use the updater function form when the new state depends on the previous state. Keep state minimal — do not store what can be computed. Lift state only as high as needed, and prefer colocating state with the component that uses it.
  10. Exercise:
    1. Build a Toggle component using state (on/off).
    2. Build a Temperature component with Celsius/Fahrenheit conversion.
    3. Explain why count = count + 1 does not re-render.
    4. Update an array in state by adding a new item immutably.
    5. Update an object in state immutably (e.g., change a user's name).

हिंदी (सरल)

  1. समस्या: Components को ऐसा data याद रखना होता है जो समय के साथ बदलता है — counter, form value, toggle, items का array। State के बिना हर बदलाव के लिए manually DOM update करना पड़ेगा और variables हर render पर reset हो जाएँगे। एक साफ तरीका चाहिए जिससे UI जिस data पर depend करता है उसे store और update किया जा सके, और बदलाव पर React अपने आप re-render करे।
  2. परिभाषा: State component का अपना mutable data है। State बदलते ही re-render होता है। Function components में local state useState hook से बनती है, जो एक pair return करता है: current value और setter function। State updates asynchronous होते हैं और immutable होने चाहिए — मौजूदा value को modify नहीं करते, नई बनाते हैं।
  3. उदाहरण: useState वाला counter और immutable array update:
    import { useState } from 'react';
    
    function Counter() {
      const [count, setCount] = useState(0);
      const [items, setItems] = useState([]);
    
      const addItem = () => {
        // सही: नया array बनाएँ
        setItems(prev => [...prev, `Item ${prev.length + 1}`]);
      };
    
      return (
        <div>
          <p>गिनती: {count}</p>
          <button onClick={() => setCount(c => c + 1)}>+1</button>
          <button onClick={() => setCount(0)}>रीसेट</button>
    
          <button onClick={addItem}>Item जोड़ें</button>
          <ul>
            {items.map((item, i) => <li key={i}>{item}</li>)}
          </ul>
        </div>
      );
    }
  4. प्रकार:
    प्रकार विवरण उदाहरण
    Local state एक component की अपनी, जैसे form input value। const [name, setName] = useState('')
    Lifted state common parent पर ले जाना ताकि siblings share कर सकें। <Parent value={x} setValue={setX} />
    Derived state props या दूसरे state से निकाला गया — अगर derivable हो तो store न करें। const total = items.length
    Global state कई components में shared (Context, Redux, Zustand)। useStore()
    Server state APIs से data जिसमें caching और syncing हो (TanStack Query)। useQuery(...)
  5. लाभ:
    • UI sync में रहता है: State बदलते ही component re-render होता है।
    • सरल API: useState सीखने और use करने में आसान।
    • Colocation: State वहीं रहती है जहाँ use होती है।
    • Predictable updates: Updates setter से जाते हैं, trace करना आसान।
    • Composable: कई useState कॉल्स साफ-सुथरे साथ रह सकते हैं।
  6. नुकसान:
    • Async updates: Set करने के तुरंत बाद पढ़ने पर पुरानी value मिलती है।
    • Direct mutate से कुछ नहीं होता: हमेशा नए objects या arrays बनाएँ।
    • Prop drilling: State बहुत ऊपर lift करने पर verbose prop passing।
    • बहुत ज़्यादा state: एक component में कई pieces से complexity बढ़ती है।
    • Derived values store करना आसान: जो out-of-sync होकर bugs पैदा करते हैं।
  7. विशेषताएँ:
    • हर useState [value, setter] देता है।
    • Setter value या updater function ले सकता है: setCount(c => c + 1)।
    • Updates batched: एक event में कई setState calls performance के लिए combine होती हैं।
    • Immutable: Objects/arrays mutate न करें — नए बनाएँ।
    • Re-render trigger: Reference या primitive equality से value बदलने पर।
  8. आरेख: State update से re-render
    setCount(count + 1)
            │
            ▼
      State update हुआ
            │
            ▼
      Component re-render
            │
            ▼
      नया JSX → diff → DOM update
    
    Immutable update pattern:
    
      // गलत
      items.push(newItem);      // कोई re-render नहीं
      setItems(items);
    
      // सही
      setItems([...items, newItem]);
      // या
      setItems(prev => [...prev, newItem]);
  9. निष्कर्ष: State ही React components को interactive बनाती है। Immutable updates और setState की asynchronous प्रकृति को समझना subtle bugs से बचने के लिए ज़रूरी है। जब नया state पुराने state पर निर्भर हो तो updater function form use करें। State minimal रखें — जो compute हो सकता है उसे store न करें। State सिर्फ ज़रूरत तक ही lift करें, और उस component के पास रखें जो use करता है।
  10. अभ्यास:
    1. State से Toggle component बनाइए (on/off)।
    2. Temperature component बनाइए जिसमें Celsius/Fahrenheit conversion हो।
    3. समझाइए कि count = count + 1 से re-render क्यों नहीं होता।
    4. State में array को immutably update करके नया item जोड़िए।
    5. State में object को immutably update कीजिए (जैसे user का नाम बदलना)।

4. React Hooks – useState, useEffect, useContext, useRef, useReducer, useMemo, useCallback

English

  1. Problem: Before Hooks (React 16.8, 2019), state and lifecycle logic could only live in class components. This forced developers to convert function components to classes just to add state, and made it hard to reuse stateful logic between components. Classes also had confusing this binding and split related logic across lifecycle methods. A better way was needed to add state, effects, and other React features to function components.
  2. Definition: Hooks are functions that let function components use state, lifecycle, and other React features. Two rules: only call hooks at the top level, and only call them from React functions. Core hooks: useState, useEffect, useContext, useRef, useReducer, useMemo, useCallback. React 18/19 adds useTransition, useDeferredValue, useId, use.
  3. Example: A timer using useState, useEffect, and useRef:
    import { useState, useEffect, useRef } from 'react';
    
    function Timer() {
      const [seconds, setSeconds] = useState(0);
      const intervalRef = useRef(null);
    
      useEffect(() => {
        intervalRef.current = setInterval(() => {
          setSeconds(s => s + 1);
        }, 1000);
    
        return () => clearInterval(intervalRef.current);
      }, []);
    
      return <p>Seconds: {seconds}</p>;
    }
  4. Types:
    Hook Purpose Example
    useState Local state in function components. const [n, setN] = useState(0)
    useEffect Side effects (fetch, subscriptions, timers) after render. useEffect(() => {}, [])
    useContext Read values from a React context. const theme = useContext(ThemeContext)
    useRef Mutable value that does not trigger re-render. const inputRef = useRef(null)
    useReducer Complex state logic with a reducer function. const [s, dispatch] = useReducer(reducer, init)
    useMemo Memoize an expensive computed value. const v = useMemo(() => calc(x), [x])
    useCallback Memoize a function reference. const fn = useCallback(() => {}, [dep])
    useTransition Mark non-urgent state updates. const [pending, start] = useTransition()
    useDeferredValue Defer a value for cheaper re-renders. const d = useDeferredValue(query)
    useId Stable IDs for accessibility. const id = useId()
  5. Advantages:
    • State in function components: No need for classes.
    • Custom hooks: Reuse stateful logic cleanly across components.
    • Less boilerplate: No constructor or lifecycle method ceremony.
    • Related logic together: Group effects by concern, not by lifecycle method.
    • Composable: One hook can call another.
    • Better testability: Hooks and components are plain functions.
  6. Disadvantages:
    • Rules of hooks: Must be followed exactly, or bugs appear.
    • Dependency arrays: Easy to get wrong, cause stale values or loops.
    • Stale closures: Effects capture values from the render they were created in.
    • Overusing useMemo/useCallback: Adds complexity without benefit.
    • Learning curve: Understanding hooks deeply takes time.
  7. Characteristics:
    • Consistent order: Hooks are called in the same order on every render.
    • Custom hooks: Functions whose names start with use.
    • Compose: Built-in hooks can be used inside custom hooks.
    • Top-level only: Cannot be called inside conditions, loops, or nested functions.
    • React functions only: Cannot be called inside plain JS functions.
  8. Diagram: Hook execution order and custom hook composition
    function Component() {
      const [a] = useState(0);   // hook 1
      const [b] = useState(1);   // hook 2
      useEffect(() => {}, []);   // hook 3
      // Order MUST remain the same every render
    }
    
    Custom Hook Example:
    
    function useWindowWidth() {
      const [w, setW] = useState(window.innerWidth);
      useEffect(() => {
        const handler = () => setW(window.innerWidth);
        window.addEventListener('resize', handler);
        return () => window.removeEventListener('resize', handler);
      }, []);
      return w;
    }
  9. Conclusion: Hooks are the foundation of modern React. They replace classes, simplify logic reuse, and make components more testable. Understanding the rules of hooks and the correct use of dependency arrays is essential for writing bug-free React code. Custom hooks let you extract and share complex behaviour without wrapper hell. Master the core hooks (useState, useEffect, useContext, useRef, useReducer, useMemo, useCallback), then reach for the newer concurrent hooks when you need them.
  10. Exercise:
    1. Write a custom hook useWindowWidth.
    2. Write a custom hook useLocalStorage.
    3. Explain why hooks cannot be called inside conditions or loops.
    4. Convert a class component with lifecycle methods into a function component with hooks.
    5. Use useReducer to build a shopping cart.

हिंदी (सरल)

  1. समस्या: Hooks (React 16.8, 2019) से पहले state और lifecycle logic सिर्फ class components में रह सकती थी। इससे developers को state जोड़ने के लिए function components को classes में बदलना पड़ता था, और stateful logic को components के बीच reuse करना मुश्किल था। Classes में confusing this binding और lifecycle methods में बँटा logic भी समस्याएँ पैदा करते थे। Function components में state, effects और दूसरे React features जोड़ने का बेहतर तरीका चाहिए था।
  2. परिभाषा: Hooks ऐसे functions हैं जो function components को state, lifecycle और दूसरे React features use करने देते हैं। दो नियम: hooks सिर्फ top level पर call करें, और सिर्फ React functions से। मुख्य hooks: useState, useEffect, useContext, useRef, useReducer, useMemo, useCallback। React 18/19 में useTransition, useDeferredValue, useId, use भी।
  3. उदाहरण: useState, useEffect और useRef वाला timer:
    import { useState, useEffect, useRef } from 'react';
    
    function Timer() {
      const [seconds, setSeconds] = useState(0);
      const intervalRef = useRef(null);
    
      useEffect(() => {
        intervalRef.current = setInterval(() => {
          setSeconds(s => s + 1);
        }, 1000);
    
        return () => clearInterval(intervalRef.current);
      }, []);
    
      return <p>सेकंड: {seconds}</p>;
    }
  4. प्रकार:
    Hook उद्देश्य उदाहरण
    useState Function components में local state। const [n, setN] = useState(0)
    useEffect Render के बाद side effects (fetch, subscriptions, timers)। useEffect(() => {}, [])
    useContext React context से values पढ़ना। const theme = useContext(ThemeContext)
    useRef Mutable value जो re-render trigger नहीं करती। const inputRef = useRef(null)
    useReducer Reducer function से complex state logic। const [s, dispatch] = useReducer(reducer, init)
    useMemo महँगी computed value memoize करना। const v = useMemo(() => calc(x), [x])
    useCallback Function reference memoize करना। const fn = useCallback(() => {}, [dep])
    useTransition Non-urgent state updates mark करना। const [pending, start] = useTransition()
    useDeferredValue Value को defer करके सस्ते re-renders। const d = useDeferredValue(query)
    useId Accessibility के लिए stable IDs। const id = useId()
  5. लाभ:
    • Function components में state: Classes की ज़रूरत नहीं।
    • Custom hooks: Stateful logic को components के बीच साफ-सुथरे reuse करना।
    • कम boilerplate: Constructor या lifecycle method की रस्म नहीं।
    • जुड़ा logic एक साथ: Effects को concern से group करें, lifecycle से नहीं।
    • Composable: एक hook दूसरे को call कर सकता है।
    • बेहतर testability: Hooks और components सादे functions हैं।
  6. नुकसान:
    • Rules of hooks: सख्ती से पालन न करने पर bugs।
    • Dependency arrays: आसानी से गलत, stale values या loops।
    • Stale closures: Effects उस render की values पकड़ लेते हैं।
    • useMemo/useCallback का अत्यधिक उपयोग: बिना लाभ complexity।
    • Learning curve: Hooks को गहराई से समझने में समय लगता है।
  7. विशेषताएँ:
    • Consistent order: हर render पर hooks एक ही क्रम में call होते हैं।
    • Custom hooks: जिनका नाम use से शुरू होता है।
    • Compose: Built-in hooks custom hooks के अंदर use कर सकते हैं।
    • Top-level only: Conditions, loops, या nested functions में नहीं।
    • React functions only: सादे JS functions में नहीं।
  8. आरेख: Hook execution order और custom hook composition
    function Component() {
      const [a] = useState(0);   // hook 1
      const [b] = useState(1);   // hook 2
      useEffect(() => {}, []);   // hook 3
      // हर render पर क्रम वही रहना चाहिए
    }
    
    Custom Hook उदाहरण:
    
    function useWindowWidth() {
      const [w, setW] = useState(window.innerWidth);
      useEffect(() => {
        const handler = () => setW(window.innerWidth);
        window.addEventListener('resize', handler);
        return () => window.removeEventListener('resize', handler);
      }, []);
      return w;
    }
  9. निष्कर्ष: Hooks आधुनिक React की नींव हैं। वे classes की जगह लेते हैं, logic reuse को सरल बनाते हैं, और components को testable बनाते हैं। Rules of hooks और dependency arrays का सही उपयोग समझना bug-free React code लिखने के लिए ज़रूरी है। Custom hooks से complex behaviour को wrapper hell के बिना extract और share कर सकते हैं। Core hooks (useState, useEffect, useContext, useRef, useReducer, useMemo, useCallback) में महारत हासिल करें, फिर नए concurrent hooks ज़रूरत पड़ने पर use करें।
  10. अभ्यास:
    1. एक custom hook useWindowWidth लिखिए।
    2. एक custom hook useLocalStorage लिखिए।
    3. समझाइए कि hooks को conditions या loops के अंदर call क्यों नहीं कर सकते।
    4. Lifecycle methods वाले class component को hooks वाले function component में बदलिए।
    5. useReducer से shopping cart बनाइए।

5. Effects & Side Effects – useEffect, Cleanup, Race Conditions

English

  1. Problem: Components often need to reach outside React — fetch data, set up timers, subscribe to events, or manipulate the DOM. Doing this directly in the render body causes infinite loops and unpredictable behaviour. Before Hooks there was no clean place in function components to run side effects and clean them up. Asynchronous fetches also caused race conditions: an older, slower request could overwrite a newer response.
  2. Definition: A side effect is anything that reaches outside React. useEffect runs after render and can return a cleanup function that runs before the next effect or on unmount. The dependency array controls when the effect re-runs.
  3. Example: Fetching data with AbortController and cleanup:
    useEffect(() => {
      const controller = new AbortController();
    
      async function load() {
        try {
          const res = await fetch('/api/users', { signal: controller.signal });
          const data = await res.json();
          setUsers(data);
        } catch (err) {
          if (err.name !== 'AbortError') setError(err);
        }
      }
      load();
    
      return () => controller.abort();
    }, []);
  4. Types:
    Dependency Array Effect Runs Use Case
    [] (empty) Once after mount, cleanup on unmount Fetch initial data, subscriptions
    [dep] After mount + whenever dep changes React to prop or state changes
    No array After every render Rarely needed
    With cleanup Cleanup runs before next effect and on unmount Timers, subscriptions, fetches
  5. Advantages:
    • Clear place for side effects: All side effects are inside useEffect, not scattered.
    • Cleanup prevents leaks: Timers, listeners, and requests are properly cancelled.
    • Fine control: Dependency array gives precise control over execution.
    • Works with async data: Standard pattern for API calls.
    • Composable: Multiple effects can coexist, each with its own concern.
  6. Disadvantages:
    • Dependency arrays easy to get wrong: Missing deps cause stale data; extra deps cause loops.
    • Race conditions: Async fetches need AbortController or a similar guard.
    • Closures: Effects capture values from the render they were created in.
    • Overuse: Many effects in one component make it hard to reason about.
    • Not for derived state: Use useMemo for computing instead.
  7. Characteristics:
    • Runs after paint: Effects do not block the browser's paint.
    • Cleanup runs first: Before each subsequent effect, and on unmount.
    • One concern per effect: Separate effects for unrelated logic.
    • Async patterns: Do not make the effect function async directly; define an inner async function.
    • AbortController: Standard way to cancel fetches.
  8. Diagram: Effect lifecycle with cleanup
    Mount → Render → Paint → useEffect runs
                                  │
                                  ▼
                            (dep changes)
                                  │
                                  ▼
                            cleanup runs
                                  │
                                  ▼
                            useEffect runs again
                                  │
                                  ▼
                            Unmount → cleanup runs last
    
    Race condition guard:
    
      1. useEffect starts fetch A (dep = 1)
      2. dep changes to 2 → cleanup aborts fetch A
      3. useEffect starts fetch B (dep = 2)
      4. Only B's result is applied
  9. Conclusion: useEffect is the correct place for side effects in function components. Handle cleanup, respect the dependency array, and always guard against race conditions when fetching data. Keep effects small and focused on one concern. For fetching, prefer a query library (TanStack Query) which handles caching, dedup, and aborting automatically.
  10. Exercise:
    1. Build a clock component using useEffect and setInterval.
    2. Fetch data from a public API and display it with loading and error states.
    3. Add a window resize listener with proper cleanup.
    4. Explain why missing cleanup causes memory leaks.
    5. Implement a fetch with AbortController to avoid race conditions.

हिंदी (सरल)

  1. समस्या: Components को अक्सर React के बाहर जाना पड़ता है — data fetch, timers, events subscribe, या DOM manipulation। यह सीधे render body में करने से infinite loops और unpredictable behaviour होता है। Hooks से पहले function components में side effects चलाने और clean करने की कोई साफ जगह नहीं थी। Asynchronous fetches में race conditions भी होती थीं: पुराना, धीमा request नए response को overwrite कर सकता था।
  2. परिभाषा: Side effect वह काम है जो React के बाहर जाता है। useEffect render के बाद चलता है और cleanup function return कर सकता है जो अगले effect से पहले या unmount पर चलता है। Dependency array तय करता है कि effect कब दोबारा चले।
  3. उदाहरण: AbortController और cleanup के साथ data fetch:
    useEffect(() => {
      const controller = new AbortController();
    
      async function load() {
        try {
          const res = await fetch('/api/users', { signal: controller.signal });
          const data = await res.json();
          setUsers(data);
        } catch (err) {
          if (err.name !== 'AbortError') setError(err);
        }
      }
      load();
    
      return () => controller.abort();
    }, []);
  4. प्रकार:
    Dependency Array Effect कब चलता है उपयोग
    [] (खाली) Mount के बाद एक बार, unmount पर cleanup Initial data fetch, subscriptions
    [dep] Mount के बाद + जब dep बदले Prop या state change पर react करना
    कोई array नहीं हर render के बाद शायद ही कभी ज़रूरत
    Cleanup के साथ Cleanup अगले effect से पहले और unmount पर Timers, subscriptions, fetches
  5. लाभ:
    • Side effects की साफ जगह: सब useEffect के अंदर, बिखरे हुए नहीं।
    • Cleanup leaks रोकता है: Timers, listeners, requests ठीक से cancel।
    • बारीक नियंत्रण: Dependency array से execution पर precise control।
    • Async data के साथ: API calls के लिए standard pattern।
    • Composable: कई effects साथ रह सकते हैं, हर एक अपने concern का।
  6. नुकसान:
    • Dependency arrays गलत होना आसान: Missing deps से stale data; extra deps से loops।
    • Race conditions: Async fetches के लिए AbortController या समान guard।
    • Closures: Effects उस render की values पकड़ लेते हैं जिसमें बने थे।
    • अत्यधिक उपयोग: एक component में कई effects logic उलझा देते हैं।
    • Derived state के लिए नहीं: Compute के लिए useMemo use करें।
  7. विशेषताएँ:
    • Paint के बाद चलता है: Effects browser को block नहीं करते।
    • Cleanup पहले चलता है: अगले effect से पहले, और unmount पर।
    • एक effect एक concern: असंबंधित logic के लिए अलग effects।
    • Async pattern: Effect function को सीधे async न बनाएँ; अंदर async function define करें।
    • AbortController: Fetches cancel करने का standard तरीका।
  8. आरेख: Cleanup के साथ Effect lifecycle
    Mount → Render → Paint → useEffect चलता है
                                  │
                                  ▼
                            (dep बदला)
                                  │
                                  ▼
                            cleanup चलता है
                                  │
                                  ▼
                            useEffect फिर चलता है
                                  │
                                  ▼
                            Unmount → cleanup आखिर में चलता है
    
    Race condition guard:
    
      1. useEffect fetch A शुरू करता है (dep = 1)
      2. dep 2 हुआ → cleanup fetch A abort करता है
      3. useEffect fetch B शुरू करता है (dep = 2)
      4. सिर्फ B का result apply होता है
  9. निष्कर्ष: Function components में side effects के लिए useEffect सही जगह है। Cleanup संभालें, dependency array का सम्मान करें, और data fetch करते समय race conditions से बचें। Effects छोटे और एक concern पर केंद्रित रखें। Fetching के लिए query library (TanStack Query) prefer करें जो caching, dedup और aborting अपने आप संभालती है।
  10. अभ्यास:
    1. useEffect और setInterval से clock component बनाइए।
    2. किसी public API से data fetch करके loading और error states के साथ दिखाइए।
    3. Proper cleanup के साथ window resize listener जोड़िए।
    4. समझाइए कि cleanup न करने से memory leaks क्यों होते हैं।
    5. Race conditions से बचने के लिए AbortController वाला fetch implement कीजिए।

6. Component Patterns – HOC, Render Props, Compound, Portals, Error Boundaries

English

  1. Problem: As apps grow, you repeatedly face the same structural problems: reusing logic across components, sharing UI structure with different content, isolating error-prone subtrees, or rendering outside the normal DOM hierarchy (modals, tooltips). Without proven patterns, every team invents its own solution, leading to inconsistent, hard-to-maintain code.
  2. Definition: Component patterns are reusable design solutions for structuring React components. Common patterns: container/presentational, higher-order components (HOC), render props, compound components, context providers, portals, error boundaries, Suspense + lazy.
  3. Example: Compound component API for Tabs:
    <Tabs>
      <Tabs.List>
        <Tabs.Tab>One</Tabs.Tab>
        <Tabs.Tab>Two</Tabs.Tab>
      </Tabs.List>
      <Tabs.Panels>
        <Tabs.Panel>Content 1</Tabs.Panel>
        <Tabs.Panel>Content 2</Tabs.Panel>
      </Tabs.Panels>
    </Tabs>
    The parent manages the active tab via context; children read it. Users get a flexible, declarative API.
  4. Types:
    Pattern Purpose Example
    Container / Presentational Split logic from UI. <UserContainer><UserView /></UserContainer>
    HOC (Higher-Order Component) Function that takes a component and returns an enhanced one. withAuth(Dashboard)
    Render Props Share logic via a function prop. <Mouse render={({x,y}) => ...} />
    Compound Components Parent + children share implicit state. <Tabs><Tabs.Tab /></Tabs>
    Context Providers Share data without prop drilling. <ThemeProvider>
    Portals Render outside the parent DOM hierarchy. ReactDOM.createPortal(<Modal />, document.body)
    Error Boundaries Catch errors in child tree and show fallback UI. <ErrorBoundary><App /></ErrorBoundary>
    Suspense + lazy Lazy load components with a fallback. <Suspense fallback={...}><Lazy /></Suspense>
  5. Advantages:
    • Reusable, proven solutions: Avoid reinventing structural problems.
    • Better separation of concerns: Logic and UI can be split cleanly.
    • Easier testing and maintenance: Well-known patterns are predictable.
    • Improved UX: Error boundaries and Suspense make apps robust.
    • Flexibility: Compound components give users a natural API.
  6. Disadvantages:
    • HOCs create wrapper hell: Deep nesting and prop collisions.
    • Render props can nest deeply: Difficult to read in extreme cases.
    • Compound components require care: Context design must be right.
    • Over-engineering: Simple components suffer from too many patterns.
    • Learning curve: Each pattern has its own semantics.
  7. Characteristics:
    • Patterns compose: You can combine HOC + Context + Error Boundary.
    • Custom hooks often replace HOC / render props: Modern React prefers hooks.
    • Portals use ReactDOM.createPortal: Still respect React event bubbling.
    • Error boundaries use class components: componentDidCatch / getDerivedStateFromError.
    • Suspense: Works with React.lazy and query libraries.
  8. Diagram: Portal and Error Boundary
    <App>
      <ErrorBoundary>
        <Main />
        {ReactDOM.createPortal(<Modal />, document.body)}
      </ErrorBoundary>
    </App>
    
    DOM Tree (portal attaches outside):
    
      body
       ├── #root
       │    └── App → ErrorBoundary → Main
       └── div.portal-root
            └── Modal
    
    ErrorBoundary flow:
    
      Child throws
           │
           ▼
      getDerivedStateFromError → set hasError=true
           │
           ▼
      Render fallback UI instead of crashed tree
  9. Conclusion: Component patterns give you a toolbox of proven solutions. Modern React favours hooks and composition over HOCs and render props, but understanding all patterns helps you read legacy code and choose the right tool. Use error boundaries and Suspense for robust, user-friendly apps. Compound components make flexible, declarative APIs. Reach for a pattern only when it solves a real problem — not because it looks clever.
  10. Exercise:
    1. Build a simple ErrorBoundary class component.
    2. Build a Modal using a React portal.
    3. Implement a compound Accordion component.
    4. Convert an HOC to a custom hook and compare the code.
    5. Implement a Suspense fallback for a lazy-loaded component.

हिंदी (सरल)

  1. समस्या: जैसे-जैसे apps बढ़ते हैं, वही structural समस्याएँ बार-बार आती हैं: components के बीच logic reuse करना, अलग content के साथ UI structure share करना, error-prone subtrees को isolate करना, या normal DOM hierarchy के बाहर render करना (modals, tooltips)। Proven patterns के बिना हर team अपना solution बनाती है, जिससे code inconsistent और hard-to-maintain हो जाता है।
  2. परिभाषा: Component patterns React components को structure करने के reusable design solutions हैं। मुख्य patterns: container/presentational, higher-order components (HOC), render props, compound components, context providers, portals, error boundaries, Suspense + lazy।
  3. उदाहरण: Tabs के लिए compound component API:
    <Tabs>
      <Tabs.List>
        <Tabs.Tab>एक</Tabs.Tab>
        <Tabs.Tab>दो</Tabs.Tab>
      </Tabs.List>
      <Tabs.Panels>
        <Tabs.Panel>सामग्री 1</Tabs.Panel>
        <Tabs.Panel>सामग्री 2</Tabs.Panel>
      </Tabs.Panels>
    </Tabs>
    Parent active tab को context से manage करता है; children पढ़ते हैं। Users को flexible, declarative API मिलती है।
  4. प्रकार:
    Pattern उद्देश्य उदाहरण
    Container / Presentational Logic को UI से अलग करना। <UserContainer><UserView /></UserContainer>
    HOC (Higher-Order Component) Function जो component लेकर enhanced component देता है। withAuth(Dashboard)
    Render Props Function prop से logic share करना। <Mouse render={({x,y}) => ...} />
    Compound Components Parent + children implicit state share करते हैं। <Tabs><Tabs.Tab /></Tabs>
    Context Providers Prop drilling के बिना data share करना। <ThemeProvider>
    Portals Parent DOM hierarchy के बाहर render करना। ReactDOM.createPortal(<Modal />, document.body)
    Error Boundaries Child tree में errors पकड़कर fallback UI दिखाना। <ErrorBoundary><App /></ErrorBoundary>
    Suspense + lazy Fallback के साथ components lazy load करना। <Suspense fallback={...}><Lazy /></Suspense>
  5. लाभ:
    • Reusable, proven solutions: Structural समस्याएँ दोबारा न बनाएँ।
    • बेहतर separation of concerns: Logic और UI साफ-सुथरे अलग।
    • Testing और maintenance आसान: जाने-पहचाने patterns predictable हैं।
    • बेहतर UX: Error boundaries और Suspense apps को robust बनाते हैं।
    • Flexibility: Compound components natural API देते हैं।
  6. नुकसान:
    • HOCs से wrapper hell: Deep nesting और prop collisions।
    • Render props deep nesting: Extreme cases में पढ़ना मुश्किल।
    • Compound components में सावधानी: Context design सही होना चाहिए।
    • Over-engineering: Simple components पर बहुत patterns।
    • Learning curve: हर pattern के अपने semantics हैं।
  7. विशेषताएँ:
    • Patterns compose: HOC + Context + Error Boundary मिला सकते हैं।
    • Custom hooks अक्सर HOC / render props की जगह: आधुनिक React hooks prefer करता है।
    • Portals ReactDOM.createPortal use करते हैं: React event bubbling फिर भी respect करते हैं।
    • Error boundaries class components: componentDidCatch / getDerivedStateFromError।
    • Suspense: React.lazy और query libraries के साथ।
  8. आरेख: Portal और Error Boundary
    <App>
      <ErrorBoundary>
        <Main />
        {ReactDOM.createPortal(<Modal />, document.body)}
      </ErrorBoundary>
    </App>
    
    DOM Tree (portal बाहर attach होता है):
    
      body
       ├── #root
       │    └── App → ErrorBoundary → Main
       └── div.portal-root
            └── Modal
    
    ErrorBoundary flow:
    
      Child throws
           │
           ▼
      getDerivedStateFromError → hasError=true
           │
           ▼
      crashed tree की जगह fallback UI render करें
  9. निष्कर्ष: Component patterns proven solutions का toolbox देते हैं। आधुनिक React HOCs और render props की तुलना में hooks और composition को प्राथमिकता देता है, लेकिन सभी patterns समझना legacy code पढ़ने और सही tool चुनने में मदद करता है। Robust, user-friendly apps के लिए error boundaries और Suspense use करें। Compound components flexible, declarative APIs देते हैं। किसी pattern को तभी अपनाएँ जब वह असली समस्या हल करे — सिर्फ clever दिखने के लिए नहीं।
  10. अभ्यास:
    1. एक simple ErrorBoundary class component बनाइए।
    2. React portal से एक Modal बनाइए।
    3. एक compound Accordion component implement कीजिए।
    4. एक HOC को custom hook में बदलकर code की तुलना कीजिए।
    5. Lazy-loaded component के लिए Suspense fallback implement कीजिए।

7. State Management – Context, Redux Toolkit, Zustand, TanStack Query

English

  1. Problem: Local useState works for one component, but real apps have data needed by many components far apart in the tree. Passing props through dozens of intermediate components (prop drilling) is painful. Server data also has its own concerns: caching, invalidation, background refetch. Mixing all of this into one solution causes complexity and bugs.
  2. Definition: State management is the practice of organising where data lives and how it changes. Three categories: local state (one component), global UI state (theme, modals, auth), and server state (data from APIs). Each has dedicated tools.
  3. Example: A minimal Zustand store:
    import { create } from 'zustand';
    
    const useStore = create((set) => ({
      count: 0,
      increment: () => set((s) => ({ count: s.count + 1 })),
      reset: () => set({ count: 0 }),
    }));
    
    function Counter() {
      const { count, increment, reset } = useStore();
      return (
        <div>
          <p>{count}</p>
          <button onClick={increment}>+1</button>
          <button onClick={reset}>Reset</button>
        </div>
      );
    }
  4. Types:
    Type of State Recommended Tools When to Use
    Local state useState, useReducer Single component or small subtree.
    Global UI state Context + useReducer, Zustand, Jotai, Redux Toolkit Theme, auth, modals, shared UI state.
    Server state TanStack Query, SWR, RTK Query, Apollo Data fetched from APIs with caching and syncing.
  5. Advantages:
    • No prop drilling: Data available anywhere in the tree.
    • Central debugging: All state changes pass through one place.
    • Server state tools: Caching, dedup, background refetch for free.
    • Small libraries: Zustand and Jotai are lightweight and simple.
    • DevTools: Redux Toolkit offers time-travel debugging.
  6. Disadvantages:
    • Extra abstraction: Redux adds boilerplate and concepts.
    • Wrong tool choice: Causes complexity and slow development.
    • Global overuse: Makes testing harder and hides dependencies.
    • Context re-renders: All consumers re-render on any change.
    • Learning curve: Each library has its own idiom.
  7. Characteristics:
    • Server state ≠ UI state: Treat separately with the right tool.
    • Global UI state should be small: Theme, auth, modals — not the whole app.
    • Redux Toolkit: Slices, Immer-based immutability, RTK Query for APIs.
    • Zustand/Jotai: Minimal, hook-based stores.
    • Context: Great for rarely changing values like theme.
  8. Diagram: Choosing a state tool
    Data needed by one component?   →  useState
    Data needed by many components? →  Context + useReducer / Zustand
    Data from an API?               →  TanStack Query / SWR
    Very large app, strict flow?    →  Redux Toolkit
    
    Layered view:
    
      ┌──────────────────────────────┐
      │  Server state (TanStack Query)│
      ├──────────────────────────────┤
      │  Global UI state (Zustand)   │
      ├──────────────────────────────┤
      │  Local state (useState)      │
      └──────────────────────────────┘
  9. Conclusion: There is no single “best” state library. Split state by type: local, global UI, and server. Use the smallest tool that solves the problem — often just useState and TanStack Query. Reach for Redux Toolkit when you need strict predictability and dev tools, Zustand when you want simplicity, and Context when the state rarely changes. Keeping each category in its own layer makes apps easier to reason about and test.
  10. Exercise:
    1. Build a theme toggle with Context + useReducer.
    2. Build a todo list with Zustand.
    3. Fetch users with TanStack Query and show loading/error states.
    4. Compare Redux Toolkit, Zustand, and Context in a short table.
    5. Refactor a prop-drilled app to use Context.

हिंदी (सरल)

  1. समस्या: Local useState एक component के लिए ठीक है, लेकिन असली apps में data कई दूर-दूर components को चाहिए। दर्जनों intermediate components से props भेजना (prop drilling) painful है। Server data के अपने concerns हैं: caching, invalidation, background refetch। सब कुछ एक solution में मिलाने से complexity और bugs बढ़ते हैं।
  2. परिभाषा: State management यह organise करने का अभ्यास है कि data कहाँ रहती है और कैसे बदलती है। तीन श्रेणियाँ: local state (एक component), global UI state (theme, modals, auth), और server state (APIs से data)। हर एक के लिए dedicated tools हैं।
  3. उदाहरण: Minimal Zustand store:
    import { create } from 'zustand';
    
    const useStore = create((set) => ({
      count: 0,
      increment: () => set((s) => ({ count: s.count + 1 })),
      reset: () => set({ count: 0 }),
    }));
    
    function Counter() {
      const { count, increment, reset } = useStore();
      return (
        <div>
          <p>{count}</p>
          <button onClick={increment}>+1</button>
          <button onClick={reset}>रीसेट</button>
        </div>
      );
    }
  4. प्रकार:
    State का प्रकार Recommended Tools कब Use करें
    Local state useState, useReducer एक component या छोटा subtree।
    Global UI state Context + useReducer, Zustand, Jotai, Redux Toolkit Theme, auth, modals, shared UI state।
    Server state TanStack Query, SWR, RTK Query, Apollo APIs से data जिसमें caching और syncing हो।
  5. लाभ:
    • Prop drilling नहीं: Data tree में कहीं भी available।
    • Central debugging: सभी state changes एक जगह से।
    • Server state tools: Caching, dedup, background refetch मुफ्त।
    • छोटी libraries: Zustand और Jotai हल्की और सरल।
    • DevTools: Redux Toolkit में time-travel debugging।
  6. नुकसान:
    • Extra abstraction: Redux से boilerplate और concepts।
    • गलत tool: Complexity और slow development।
    • Global अत्यधिक उपयोग: Testing मुश्किल, dependencies छिपती हैं।
    • Context re-renders: हर बदलाव पर सभी consumers re-render।
    • Learning curve: हर library की अपनी idiom।
  7. विशेषताएँ:
    • Server state ≠ UI state: सही tool से अलग treat करें।
    • Global UI state छोटी: Theme, auth, modals — पूरा app नहीं।
    • Redux Toolkit: Slices, Immer-based immutability, APIs के लिए RTK Query।
    • Zustand/Jotai: Minimal, hook-based stores।
    • Context: Rarely बदलने वाली values जैसे theme के लिए बढ़िया।
  8. आरेख: State tool चुनना
    Data एक component को चाहिए?     →  useState
    Data कई components को चाहिए?    →  Context + useReducer / Zustand
    Data API से आता है?             →  TanStack Query / SWR
    बहुत बड़ा app, strict flow?     →  Redux Toolkit
    
    Layered view:
    
      ┌──────────────────────────────┐
      │  Server state (TanStack Query)│
      ├──────────────────────────────┤
      │  Global UI state (Zustand)   │
      ├──────────────────────────────┤
      │  Local state (useState)      │
      └──────────────────────────────┘
  9. निष्कर्ष: कोई एक “best” state library नहीं है। State को type से बाँटें: local, global UI, और server। सबसे छोटा tool use करें जो समस्या हल करे — अक्सर useState और TanStack Query। जब strict predictability और dev tools चाहिए तो Redux Toolkit, simplicity चाहिए तो Zustand, और rarely बदलने वाली state के लिए Context। हर category को उसकी अपनी layer में रखने से apps समझने और test करने में आसान हो जाते हैं।
  10. अभ्यास:
    1. Context + useReducer से theme toggle बनाइए।
    2. Zustand से todo list बनाइए।
    3. TanStack Query से users fetch करके loading/error states दिखाइए।
    4. Redux Toolkit, Zustand, और Context की छोटी table में तुलना कीजिए।
    5. Prop-drilled app को Context से refactor कीजिए।

8. Routing & Navigation – React Router, Nested Routes, Protected Routes

English

  1. Problem: A single-page React app has one HTML page. But users still expect URLs like /users/42 and /dashboard, the back button, bookmarking, and deep links. Without a router, you would need full page reloads or manual history manipulation. SEO, analytics, and share links all depend on real URLs.
  2. Definition: Client-side routing maps URLs to components without a full page reload. React Router is the de-facto standard. It supports nested routes, route params, query strings, programmatic navigation, protected routes, and lazy-loaded routes.
  3. Example: Basic routing with React Router v6:
    import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
    
    function App() {
      return (
        <BrowserRouter>
          <Routes>
            <Route path="/" element={<Home />} />
    
            <Route path="/users" element={<UsersLayout />}>
              <Route index element={<UsersList />} />
              <Route path=":id" element={<UserDetail />} />
            </Route>
    
            <Route path="/dashboard" element={
              <ProtectedRoute><Dashboard /></ProtectedRoute>
            } />
    
            <Route path="*" element={<NotFound />} />
          </Routes>
        </BrowserRouter>
      );
    }
  4. Types:
    Concept Description Hook / API
    Nested routes Child routes rendered inside a parent layout. <Outlet />
    Route params Dynamic segments like :id. useParams()
    Query strings Read/write URL query parameters. useSearchParams()
    Programmatic navigation Push/replace routes in code. useNavigate()
    Protected routes Wrapper that redirects unauthenticated users. <Navigate to="/login" />
    Lazy routes Code split per route. React.lazy + Suspense
  5. Advantages:
    • Real URLs: Back/forward buttons, bookmarks, share links work.
    • Fast navigation: No full page reloads.
    • Nested layouts: Shared shells for sections of the app.
    • Protected routes: Easy auth gating.
    • Code splitting per route: Smaller initial bundle.
  6. Disadvantages:
    • Extra dependency: Adds to bundle size.
    • Server config: Must serve index.html for all routes.
    • SEO limits: Full benefit needs SSR/SSG.
    • Complex configs: Deeply nested routes can be hard to follow.
  7. Characteristics:
    • Route matching by specificity: Not by order.
    • Outlet renders children: Used for nested layouts.
    • Data APIs: Loaders and actions in v6.4+.
    • File-based routing: Next.js and Remix build on the same concepts.
    • Lazy loading: Per route via React.lazy.
  8. Diagram: Route tree with nested layout and protected route
    <BrowserRouter>
     └─ <Routes>
         ├─ "/"              → <Home />
         ├─ "/users"         → <UsersLayout />
         │     ├─ index      → <UsersList />
         │     └─ ":id"      → <UserDetail />
         ├─ "/dashboard"     → <ProtectedRoute> → <Dashboard />
         └─ "*"              → <NotFound />
    
    ProtectedRoute example:
    
      function ProtectedRoute({ children }) {
        const authed = useAuth();
        return authed ? children : <Navigate to="/login" replace />;
      }
  9. Conclusion: Routing is essential for any real React app. React Router gives you URL-driven navigation, nested layouts, dynamic params, and protected routes. Lazy-load route components to keep bundles small. When using Next.js or Remix you get file-based routing on top of the same concepts, plus server rendering. Always test navigation flows including the back button and deep links.
  10. Exercise:
    1. Set up React Router with Home, About, and Contact pages.
    2. Create a nested route with a shared layout using <Outlet />.
    3. Read a route param and query string.
    4. Implement a ProtectedRoute that redirects to /login.
    5. Lazy-load a route component with Suspense.

हिंदी (सरल)

  1. समस्या: Single-page React app में एक ही HTML page होता है। लेकिन users अभी भी /users/42 और /dashboard जैसे URLs, back button, bookmarking और deep links expect करते हैं। Router के बिना full page reloads या manual history manipulation करनी पड़ेगी। SEO, analytics और share links सब असली URLs पर depend करते हैं।
  2. परिभाषा: Client-side routing URLs को components से जोड़ता है, बिना पूरा page reload किए। React Router standard है। यह nested routes, route params, query strings, programmatic navigation, protected routes और lazy-loaded routes support करता है।
  3. उदाहरण: React Router v6 से basic routing:
    import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
    
    function App() {
      return (
        <BrowserRouter>
          <Routes>
            <Route path="/" element={<Home />} />
    
            <Route path="/users" element={<UsersLayout />}>
              <Route index element={<UsersList />} />
              <Route path=":id" element={<UserDetail />} />
            </Route>
    
            <Route path="/dashboard" element={
              <ProtectedRoute><Dashboard /></ProtectedRoute>
            } />
    
            <Route path="*" element={<NotFound />} />
          </Routes>
        </BrowserRouter>
      );
    }
  4. प्रकार:
    Concept विवरण Hook / API
    Nested routes Child routes parent layout के अंदर render। <Outlet />
    Route params :id जैसे dynamic segments। useParams()
    Query strings URL query parameters read/write। useSearchParams()
    Programmatic navigation Code में push/replace। useNavigate()
    Protected routes Wrapper जो unauthenticated users को redirect करता है। <Navigate to="/login" />
    Lazy routes प्रति route code split। React.lazy + Suspense
  5. लाभ:
    • असली URLs: Back/forward buttons, bookmarks, share links काम करते हैं।
    • तेज़ navigation: Full page reload नहीं।
    • Nested layouts: App के sections के लिए shared shells।
    • Protected routes: Auth gating आसान।
    • Per route code splitting: छोटा initial bundle।
  6. नुकसान:
    • Extra dependency: Bundle size बढ़ती है।
    • Server config: सभी routes के लिए index.html serve करना पड़ता है।
    • SEO limits: पूरा लाभ SSR/SSG चाहिए।
    • Complex configs: Deeply nested routes follow करना मुश्किल।
  7. विशेषताएँ:
    • Route matching specificity से: Order से नहीं।
    • Outlet children render करता है: Nested layouts के लिए।
    • Data APIs: v6.4+ में loaders और actions।
    • File-based routing: Next.js और Remix उन्हीं concepts पर।
    • Lazy loading: प्रति route React.lazy से।
  8. आरेख: Nested layout और protected route वाला route tree
    <BrowserRouter>
     └─ <Routes>
         ├─ "/"              → <Home />
         ├─ "/users"         → <UsersLayout />
         │     ├─ index      → <UsersList />
         │     └─ ":id"      → <UserDetail />
         ├─ "/dashboard"     → <ProtectedRoute> → <Dashboard />
         └─ "*"              → <NotFound />
    
    ProtectedRoute उदाहरण:
    
      function ProtectedRoute({ children }) {
        const authed = useAuth();
        return authed ? children : <Navigate to="/login" replace />;
      }
  9. निष्कर्ष: किसी भी असली React app के लिए routing ज़रूरी है। React Router URL-driven navigation, nested layouts, dynamic params और protected routes देता है। Bundles छोटे रखने के लिए route components lazy-load करें। Next.js या Remix में वही concepts file-based routing के साथ मिलते हैं, साथ ही server rendering। हमेशा navigation flows test करें — back button और deep links सहित।
  10. अभ्यास:
    1. Home, About, Contact pages के साथ React Router set up कीजिए।
    2. <Outlet /> से shared layout वाला nested route बनाइए।
    3. Route param और query string पढ़िए।
    4. ProtectedRoute implement कीजिए जो /login पर redirect करे।
    5. Suspense के साथ एक route component lazy-load कीजिए।

9. Forms & User Input – Controlled Components, React Hook Form, Validation

English

  1. Problem: Forms are where users enter data — login, signup, checkout, search. Handling many inputs with useState leads to verbose code, plus you need validation, error messages, loading states, and file inputs. Doing this manually for every form is repetitive and error-prone. Poor validation leads to bad UX and insecure backends.
  2. Definition: A controlled component keeps its value in React state, with value and onChange wired together. An uncontrolled component keeps its value in the DOM and is read via refs. Libraries like React Hook Form (RHF) and Formik reduce boilerplate and add validation. Server-side validation must always complement client-side validation.
  3. Example: React Hook Form with validation:
    import { useForm } from 'react-hook-form';
    
    function LoginForm() {
      const {
        register, handleSubmit,
        formState: { errors, isSubmitting }
      } = useForm();
    
      const onSubmit = async (data) => {
        await fetch('/api/login', {
          method: 'POST',
          body: JSON.stringify(data),
        });
      };
    
      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <input
            {...register('email', {
              required: 'Email is required',
              pattern: { value: /\\S+@\\S+/, message: 'Invalid email' }
            })}
          />
          {errors.email && <span>{errors.email.message}</span>}
    
          <input
            type="password"
            {...register('password', { required: true, minLength: 8 })}
          />
          {errors.password && <span>Password too short</span>}
    
          <button disabled={isSubmitting}>
            {isSubmitting ? 'Logging in...' : 'Login'}
          </button>
        </form>
      );
    }
  4. Types:
    Type Description
    Controlled Value lives in React state; source of truth is React.
    Uncontrolled Value lives in DOM; read via refs.
    React Hook Form Uncontrolled-based library with minimal re-renders.
    Formik Controlled-based library, popular in older code.
    Server Actions / useActionState React 19 form submission with server functions.
    Schema validation (Zod, Yup) Type-safe validation rules shared between client and server.
  5. Advantages:
    • Validation, error display, submission: Handled uniformly.
    • Less boilerplate: React Hook Form significantly reduces code.
    • Better performance: Uncontrolled inputs avoid re-renders.
    • Schema validation: Zod/Yup make rules reusable and typed.
    • Loading states: Built-in isSubmitting for UX feedback.
  6. Disadvantages:
    • Controlled forms with many inputs: Cause excessive re-renders.
    • Library learning curve: RHF has its own idioms.
    • Server validation still required: For security.
    • File inputs and complex widgets: Need special handling.
    • Debugging uncontrolled inputs: Slightly harder than controlled.
  7. Characteristics:
    • Client + server validation: Both are required.
    • Controlled inputs: Make conditional UI easy.
    • Uncontrolled inputs: Lighter but harder to coordinate.
    • Disable submit while submitting: Prevent double posts.
    • Accessible errors: Use aria-invalid and aria-describedby.
  8. Diagram: Controlled vs uncontrolled
    Controlled:
      state ── value ──► input
        ▲                  │
        └──── onChange ◄────┘
    
    Uncontrolled:
      input (DOM holds value)
        │
        └── read via ref on submit
    
    Form submission flow:
    
      User fills form
            │
            ▼
      Client validation (instant feedback)
            │
            ▼
      POST to server
            │
            ▼
      Server validation (final gate)
            │
            ▼
      Success / error response
  9. Conclusion: Forms are a core part of every app. Learn both controlled and uncontrolled patterns, then reach for React Hook Form for anything non-trivial. Always pair client-side validation with server-side validation, and show clear loading/error states to the user. Use schema validation with Zod/Yup for reusable, typed rules. Handle file inputs and complex widgets separately, testing on multiple browsers.
  10. Exercise:
    1. Build a controlled login form with two fields.
    2. Rebuild it with React Hook Form and compare the code.
    3. Add client-side validation for email and password length.
    4. Add a file upload input and handle it in onSubmit.
    5. Integrate Zod schema validation into React Hook Form.

हिंदी (सरल)

  1. समस्या: Forms वह जगह हैं जहाँ users data डालते हैं — login, signup, checkout, search। कई inputs को useState से संभालने पर code बहुत लंबा हो जाता है, और validation, error messages, loading states, file inputs भी चाहिए। हर form के लिए manually यह करना repetitive और error-prone है। खराब validation से UX खराब और backend असुरक्षित होता है।
  2. परिभाषा: Controlled component अपनी value React state में रखता है, जिसमें value और onChange जुड़े होते हैं। Uncontrolled component value DOM में रखता है और refs से पढ़ी जाती है। React Hook Form (RHF) और Formik जैसी libraries boilerplate कम करती हैं और validation जोड़ती हैं। Server-side validation हमेशा client-side validation के साथ होनी चाहिए।
  3. उदाहरण: Validation के साथ React Hook Form:
    import { useForm } from 'react-hook-form';
    
    function LoginForm() {
      const {
        register, handleSubmit,
        formState: { errors, isSubmitting }
      } = useForm();
    
      const onSubmit = async (data) => {
        await fetch('/api/login', {
          method: 'POST',
          body: JSON.stringify(data),
        });
      };
    
      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <input
            {...register('email', {
              required: 'Email ज़रूरी है',
              pattern: { value: /\\S+@\\S+/, message: 'गलत email' }
            })}
          />
          {errors.email && <span>{errors.email.message}</span>}
    
          <input
            type="password"
            {...register('password', { required: true, minLength: 8 })}
          />
          {errors.password && <span>पासवर्ड छोटा है</span>}
    
          <button disabled={isSubmitting}>
            {isSubmitting ? 'लॉगिन हो रहा है...' : 'लॉगिन'}
          </button>
        </form>
      );
    }
  4. प्रकार:
    प्रकार विवरण
    Controlled Value React state में; source of truth React।
    Uncontrolled Value DOM में; refs से पढ़ें।
    React Hook Form Uncontrolled-based library, कम re-renders।
    Formik Controlled-based library, पुराने code में popular।
    Server Actions / useActionState React 19 में server functions से form submission।
    Schema validation (Zod, Yup) Type-safe validation rules जो client और server में share होती हैं।
  5. लाभ:
    • Validation, error display, submission: एक समान तरीके से।
    • कम boilerplate: React Hook Form से code काफी कम।
    • बेहतर performance: Uncontrolled inputs से re-renders कम।
    • Schema validation: Zod/Yup से rules reusable और typed।
    • Loading states: Built-in isSubmitting से UX feedback।
  6. नुकसान:
    • कई inputs वाले controlled forms: ज़्यादा re-renders।
    • Library की learning curve: RHF की अपनी idioms।
    • Server validation फिर भी ज़रूरी: Security के लिए।
    • File inputs और complex widgets: Special handling।
    • Uncontrolled inputs debug करना: Controlled से थोड़ा मुश्किल।
  7. विशेषताएँ:
    • Client + server validation: दोनों ज़रूरी।
    • Controlled inputs: Conditional UI आसान।
    • Uncontrolled inputs: हल्के पर coordinate करना मुश्किल।
    • Submit के दौरान button disable: Double posts रोकें।
    • Accessible errors: aria-invalid और aria-describedby use करें।
  8. आरेख: Controlled vs uncontrolled
    Controlled:
      state ── value ──► input
        ▲                  │
        └──── onChange ◄────┘
    
    Uncontrolled:
      input (DOM value रखता है)
        │
        └── submit पर ref से पढ़ें
    
    Form submission flow:
    
      User form भरता है
            │
            ▼
      Client validation (तुरंत feedback)
            │
            ▼
      Server को POST
            │
            ▼
      Server validation (final gate)
            │
            ▼
      Success / error response
  9. निष्कर्ष: Forms हर app का core हिस्सा हैं। Controlled और uncontrolled दोनों patterns सीखें, फिर किसी भी non-trivial form के लिए React Hook Form use करें। Client-side validation के साथ हमेशा server-side validation रखें, और user को clear loading/error states दिखाएँ। Reusable, typed rules के लिए Zod/Yup से schema validation करें। File inputs और complex widgets अलग संभालें, कई browsers पर test करें।
  10. अभ्यास:
    1. दो fields वाला controlled login form बनाइए।
    2. उसे React Hook Form से दोबारा बनाकर code की तुलना कीजिए।
    3. Email और password length के लिए client-side validation जोड़िए।
    4. File upload input जोड़कर onSubmit में संभालिए।
    5. Zod schema validation को React Hook Form में integrate कीजिए।

10. Data Fetching & APIs – Fetch, Axios, TanStack Query, SWR, GraphQL

English

  1. Problem: Almost every React app needs data from a server. Doing this with raw fetch inside useEffect means you must manually handle loading states, errors, caching, refetching, deduplication, and race conditions. This is a lot of repetitive, error-prone code. Server state is fundamentally different from UI state and deserves its own tools.
  2. Definition: Data fetching is retrieving data from a backend over HTTP (REST) or a query language (GraphQL). Tools like TanStack Query (React Query), SWR, and RTK Query provide caching, background refetch, deduplication, retries, and a rich hook API out of the box.
  3. Example: TanStack Query in action:
    import { useQuery, useMutation, useQueryClient }
      from '@tanstack/react-query';
    
    function Users() {
      const qc = useQueryClient();
    
      const { data, isLoading, error, refetch } = useQuery({
        queryKey: ['users'],
        queryFn: () => fetch('/api/users').then(r => r.json()),
      });
    
      const createUser = useMutation({
        mutationFn: (user) => fetch('/api/users', {
          method: 'POST', body: JSON.stringify(user),
        }),
        onSuccess: () => qc.invalidateQueries({ queryKey: ['users'] }),
      });
    
      if (isLoading) return <Spinner />;
      if (error) return <ErrorMsg error={error} onRetry={refetch} />;
    
      return (
        <>
          <UserList users={data} />
          <button onClick={() => createUser.mutate({ name: 'New' })}>
            Add User
          </button>
        </>
      );
    }
  4. Types:
    Tool Type Best For
    fetch Browser API Simple one-off requests
    Axios HTTP client Interceptors, request configs, timeouts
    TanStack Query Server-state library Caching, mutations, infinite scroll, pagination
    SWR Server-state library Lightweight alternative, stale-while-revalidate
    RTK Query Redux Toolkit add-on Apps already using Redux
    Apollo / urql GraphQL clients GraphQL APIs
  5. Advantages:
    • Caching and dedup: Out of the box.
    • Background refetch: Keeps data fresh without user action.
    • Standardised states: loading, error, success all uniform.
    • Mutations with optimistic updates: Instant UI feedback.
    • Pagination and infinite scroll: Dedicated hooks (useInfiniteQuery).
    • Retries and cancellation: Configurable out of the box.
  6. Disadvantages:
    • Extra dependency: Learning curve and bundle size.
    • Query keys: Must be designed carefully for correct caching.
    • Over-fetching: Poor cache strategy wastes bandwidth.
    • GraphQL: Needs a well-designed schema and server.
    • Another layer: Debugging requires understanding both React and the library.
  7. Characteristics:
    • Server state ≠ UI state: Treat separately.
    • Keys identify cached data: ['users'], ['user', id].
    • Mutations invalidate queries: Automatic refetch after data changes.
    • AbortController: Cancels in-flight requests.
    • Optimistic updates: Show the expected result before the server confirms.
  8. Diagram: Query lifecycle
    Component mounts
            │
            ▼
    useQuery(key, fn)
            │
            ▼
      Cache hit? ── yes → return cached + refetch in background
            │
            no
            ▼
      Fetch → loading → success/error
            │
            ▼
      Cache stored under key
            │
            ▼
      Mutations invalidate → refetch
    
    Optimistic update flow:
    
      User clicks "Add"
            │
            ▼
      UI shows new item immediately
            │
            ▼
      Server request in background
            │
            ▼
      On success → keep / refetch
      On error   → rollback
  9. Conclusion: Use TanStack Query (or SWR) for all server state. Keep fetch/Axios for simple cases and as the low-level engine inside your query functions. This separation — server state in a query library, UI state in React — makes apps dramatically simpler, faster, and more predictable. Design query keys carefully, and use optimistic updates for a snappy feel.
  10. Exercise:
    1. Fetch a list from a public API using fetch and useState/useEffect.
    2. Rebuild the same with TanStack Query and compare the code.
    3. Add a mutation that creates a new item and invalidates the list query.
    4. Implement infinite scroll with useInfiniteQuery.
    5. Add an optimistic update for a like/unlike action.

हिंदी (सरल)

  1. समस्या: लगभग हर React app को server से data चाहिए। इसे useEffect के अंदर raw fetch से करने पर loading states, errors, caching, refetching, deduplication और race conditions manually संभालने पड़ते हैं। यह बहुत repetitive, error-prone code है। Server state असल में UI state से fundamentally अलग है और उसके अपने tools चाहिए।
  2. परिभाषा: Data fetching HTTP (REST) या query language (GraphQL) पर backend से data लाना है। TanStack Query (React Query), SWR और RTK Query जैसे tools caching, background refetch, deduplication, retries और समृद्ध hook API out of the box देते हैं।
  3. उदाहरण: TanStack Query का उपयोग:
    import { useQuery, useMutation, useQueryClient }
      from '@tanstack/react-query';
    
    function Users() {
      const qc = useQueryClient();
    
      const { data, isLoading, error, refetch } = useQuery({
        queryKey: ['users'],
        queryFn: () => fetch('/api/users').then(r => r.json()),
      });
    
      const createUser = useMutation({
        mutationFn: (user) => fetch('/api/users', {
          method: 'POST', body: JSON.stringify(user),
        }),
        onSuccess: () => qc.invalidateQueries({ queryKey: ['users'] }),
      });
    
      if (isLoading) return <Spinner />;
      if (error) return <ErrorMsg error={error} onRetry={refetch} />;
    
      return (
        <>
          <UserList users={data} />
          <button onClick={() => createUser.mutate({ name: 'नया' })}>
            User जोड़ें
          </button>
        </>
      );
    }
  4. प्रकार:
    Tool प्रकार सबसे अच्छा
    fetch Browser API Simple one-off requests
    Axios HTTP client Interceptors, request configs, timeouts
    TanStack Query Server-state library Caching, mutations, infinite scroll, pagination
    SWR Server-state library हल्का विकल्प, stale-while-revalidate
    RTK Query Redux Toolkit add-on जो apps पहले से Redux use करते हैं
    Apollo / urql GraphQL clients GraphQL APIs
  5. लाभ:
    • Caching और dedup: Out of the box।
    • Background refetch: बिना user action data ताज़ा।
    • Standardised states: loading, error, success सब uniform।
    • Optimistic updates के साथ mutations: Instant UI feedback।
    • Pagination और infinite scroll: Dedicated hooks (useInfiniteQuery)।
    • Retries और cancellation: Configurable out of the box।
  6. नुकसान:
    • Extra dependency: Learning curve और bundle size।
    • Query keys: Correct caching के लिए सावधानी से design।
    • Over-fetching: खराब cache strategy bandwidth बर्बाद करती है।
    • GraphQL: अच्छा schema और server चाहिए।
    • Another layer: Debugging के लिए React और library दोनों समझना पड़ता है।
  7. विशेषताएँ:
    • Server state ≠ UI state: अलग treat करें।
    • Keys cached data identify करती हैं: ['users'], ['user', id]।
    • Mutations queries invalidate करती हैं: Data बदलने पर automatic refetch।
    • AbortController: In-flight requests cancel।
    • Optimistic updates: Server confirm से पहले expected result दिखाएँ।
  8. आरेख: Query lifecycle
    Component mount
            │
            ▼
    useQuery(key, fn)
            │
            ▼
      Cache hit? ── हाँ → cached + background refetch
            │
            नहीं
            ▼
      Fetch → loading → success/error
            │
            ▼
      Cache key के नीचे stored
            │
            ▼
      Mutations invalidate → refetch
    
    Optimistic update flow:
    
      User "Add" क्लिक करता है
            │
            ▼
      UI नया item तुरंत दिखाता है
            │
            ▼
      Background में server request
            │
            ▼
      Success → रखें / refetch
      Error   → rollback
  9. निष्कर्ष: सभी server state के लिए TanStack Query (या SWR) use करें। fetch/Axios simple cases और query functions के low-level engine के रूप में रखें। यह separation — server state query library में, UI state React में — apps को dramatically simpler, तेज़ और predictable बनाता है। Query keys सावधानी से design करें, और snappy feel के लिए optimistic updates use करें।
  10. अभ्यास:
    1. किसी public API से fetch और useState/useEffect से list fetch कीजिए।
    2. वही TanStack Query से बनाकर code की तुलना कीजिए।
    3. एक mutation जोड़िए जो नया item बनाए और list query invalidate करे।
    4. useInfiniteQuery से infinite scroll implement कीजिए।
    5. Like/unlike action के लिए optimistic update जोड़िए।

11. Dynamic UI & Interactivity – Conditional Rendering, Animations, Modals, Virtualization, a11y

English

  1. Problem: Users expect rich, interactive interfaces — modals, dropdowns, tooltips, animated transitions, drag-and-drop, virtualized lists of 10,000 items, and accessibility. Building all of this from scratch in React is time-consuming and easy to get wrong. Accessibility especially suffers when keyboard navigation and focus management are forgotten.
  2. Definition: Dynamic UI in React covers conditional rendering, animations (Framer Motion, React Spring), overlay components (modals, tooltips, dropdowns), virtualized lists (react-window, TanStack Virtual), drag-and-drop (dnd-kit), charts, and accessibility (ARIA, focus management, keyboard navigation).
  3. Example: Animated modal with Framer Motion:
    import { motion, AnimatePresence } from 'framer-motion';
    
    function Modal({ isOpen, onClose, children }) {
      return (
        <AnimatePresence>
          {isOpen && (
            <motion.div
              className="overlay"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              onClick={onClose}
              role="dialog"
              aria-modal="true"
            >
              <motion.div
                className="modal"
                initial={{ y: 40, opacity: 0 }}
                animate={{ y: 0, opacity: 1 }}
                exit={{ y: 40, opacity: 0 }}
                onClick={e => e.stopPropagation()}
              >
                {children}
              </motion.div>
            </motion.div>
          )}
        </AnimatePresence>
      );
    }
  4. Types:
    Category Examples
    Conditional rendering &&, ternary, early return
    Animations Framer Motion, React Spring, CSS transitions
    Overlays Modals, tooltips, dropdowns, popovers (Radix, Headless UI)
    Virtualized lists react-window, react-virtualized, TanStack Virtual
    Drag-and-drop dnd-kit, react-beautiful-dnd
    Accessibility ARIA roles, focus trap, keyboard navigation
    Charts Recharts, visx, Chart.js with React
  5. Advantages:
    • Delightful UX: Modern, polished experiences.
    • Accessible components: Proven libraries handle ARIA correctly.
    • Performance: Virtualization makes huge lists usable.
    • Focus management: Improves keyboard and screen-reader UX.
    • Reusability: Radix/Headless UI give unstyled primitives.
  6. Disadvantages:
    • Performance risk: Animations can hurt FPS if not optimised.
    • Accessibility easy to get wrong: Test with real users.
    • Overuse of effects: Overwhelms users.
    • Bundle weight: Third-party libraries add size.
    • Complexity: Managing modals, focus, and scroll-lock is fiddly.
  7. Characteristics:
    • Prefer CSS for simple animations: JS for complex choreography.
    • Modals should trap focus: Close on Escape.
    • Virtualize lists over a few hundred items.
    • Follow WAI-ARIA patterns: For interactive widgets.
    • Respect prefers-reduced-motion: Disable animations for users who request it.
  8. Diagram: Modal focus trap
    Open modal
       │
       ▼
    Save current focus
       │
       ▼
    Focus first focusable element in modal
       │
       ▼
    Tab / Shift+Tab cycles inside modal
       │
       ▼
    Escape / click overlay → close
       │
       ▼
    Restore previous focus
    
    Virtualized list rendering:
    
      Full list (10,000 items):
       [1] [2] [3] ... [10000]
    
      Virtualized (visible window only):
       [9998] [9999] [10000]  ← rendered
       rest is placeholder space
  9. Conclusion: Great UX is a combination of good design, thoughtful interactions, and accessibility. Use battle-tested libraries for overlays and animation instead of reinventing them. Always test with keyboard and screen readers. Performance and accessibility are not afterthoughts; they are part of the design. Reach for Radix or Headless UI when building custom components.
  10. Exercise:
    1. Build an accessible modal with focus trap and Escape to close.
    2. Add enter/exit animations to a dropdown menu.
    3. Virtualize a list of 10,000 rows with react-window.
    4. Run a Lighthouse accessibility audit and fix the issues.
    5. Respect prefers-reduced-motion in your animations.

हिंदी (सरल)

  1. समस्या: Users rich, interactive interfaces expect करते हैं — modals, dropdowns, tooltips, animated transitions, drag-and-drop, 10,000 items की virtualized lists, और accessibility। यह सब React में scratch से बनाना time-consuming और error-prone है। Accessibility खासकर तब खराब होती है जब keyboard navigation और focus management भूल जाते हैं।
  2. परिभाषा: React में Dynamic UI में conditional rendering, animations (Framer Motion, React Spring), overlay components (modals, tooltips, dropdowns), virtualized lists (react-window, TanStack Virtual), drag-and-drop (dnd-kit), charts, और accessibility (ARIA, focus management, keyboard navigation) शामिल हैं।
  3. उदाहरण: Framer Motion से animated modal:
    import { motion, AnimatePresence } from 'framer-motion';
    
    function Modal({ isOpen, onClose, children }) {
      return (
        <AnimatePresence>
          {isOpen && (
            <motion.div
              className="overlay"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              onClick={onClose}
              role="dialog"
              aria-modal="true"
            >
              <motion.div
                className="modal"
                initial={{ y: 40, opacity: 0 }}
                animate={{ y: 0, opacity: 1 }}
                exit={{ y: 40, opacity: 0 }}
                onClick={e => e.stopPropagation()}
              >
                {children}
              </motion.div>
            </motion.div>
          )}
        </AnimatePresence>
      );
    }
  4. प्रकार:
    श्रेणी उदाहरण
    Conditional rendering &&, ternary, early return
    Animations Framer Motion, React Spring, CSS transitions
    Overlays Modals, tooltips, dropdowns, popovers (Radix, Headless UI)
    Virtualized lists react-window, react-virtualized, TanStack Virtual
    Drag-and-drop dnd-kit, react-beautiful-dnd
    Accessibility ARIA roles, focus trap, keyboard navigation
    Charts Recharts, visx, Chart.js with React
  5. लाभ:
    • Delightful UX: Modern, polished अनुभव।
    • Accessible components: Proven libraries ARIA सही संभालती हैं।
    • Performance: Virtualization से बड़ी lists usable।
    • Focus management: Keyboard और screen-reader UX सुधारता है।
    • Reusability: Radix/Headless UI unstyled primitives देते हैं।
  6. नुकसान:
    • Performance risk: Animations FPS खराब कर सकते हैं।
    • Accessibility आसानी से गलत: असली users से test करें।
    • Effects का अत्यधिक उपयोग: Users overwhelm होते हैं।
    • Bundle weight: Third-party libraries size बढ़ाती हैं।
    • Complexity: Modals, focus, scroll-lock संभालना fiddly।
  7. विशेषताएँ:
    • Simple animations के लिए CSS: Complex choreography के लिए JS।
    • Modals focus trap करें: Escape पर बंद।
    • कुछ सौ से ज़्यादा items virtualize करें।
    • WAI-ARIA patterns follow करें: Interactive widgets के लिए।
    • prefers-reduced-motion respect करें: जो users चाहते हैं उनके लिए animations बंद।
  8. आरेख: Modal focus trap
    Modal खोलें
       │
       ▼
    Current focus save करें
       │
       ▼
    Modal के पहले focusable element पर focus
       │
       ▼
    Tab / Shift+Tab modal के अंदर cycle करें
       │
       ▼
    Escape / overlay click → बंद
       │
       ▼
    पिछला focus restore करें
    
    Virtualized list rendering:
    
      Full list (10,000 items):
       [1] [2] [3] ... [10000]
    
      Virtualized (सिर्फ visible window):
       [9998] [9999] [10000]  ← rendered
       बाकी placeholder space
  9. निष्कर्ष: बेहतरीन UX अच्छे design, thoughtful interactions और accessibility का मेल है। Overlays और animation के लिए battle-tested libraries use करें, खुद न बनाएँ। हमेशा keyboard और screen readers से test करें। Performance और accessibility afterthought नहीं, design का हिस्सा हैं। Custom components बनाते समय Radix या Headless UI consider करें।
  10. अभ्यास:
    1. Focus trap और Escape से बंद होने वाला accessible modal बनाइए।
    2. Dropdown menu में enter/exit animations जोड़िए।
    3. react-window से 10,000 rows की list virtualize कीजिए।
    4. Lighthouse accessibility audit चलाकर issues fix कीजिए।
    5. अपने animations में prefers-reduced-motion respect कीजिए।

12. Performance Optimization – Memo, useMemo, useCallback, Code Splitting, Profiler

English

  1. Problem: React re-renders components whenever state or props change. In large apps, unnecessary renders cause sluggish UIs, dropped frames, and high CPU. Without measuring, developers often optimise the wrong thing or add complexity for no gain. Large JavaScript bundles also slow down the first paint.
  2. Definition: Performance optimisation in React is the practice of reducing unnecessary work: re-renders, expensive computations, and bundle size. Key tools: React.memo, useMemo, useCallback, React.lazy + Suspense, virtualisation, and the React DevTools Profiler.
  3. Example: Memoizing a heavy child and a stable callback:
    const MemoChild = React.memo(function Child({ value, onClick }) {
      return <button onClick={onClick}>{value}</button>;
    });
    
    function Parent({ data, id }) {
      const handleClick = useCallback(() => doSomething(id), [id]);
      const result = useMemo(() => expensiveCalc(data), [data]);
    
      return <MemoChild value={result} onClick={handleClick} />;
    }
  4. Types:
    Technique Purpose When to Use
    React.memo Skip re-render if props are unchanged. Child re-renders with same props.
    useMemo Cache an expensive computed value. Heavy computation in render.
    useCallback Cache a function reference. Memoized child needs stable callback.
    Code splitting React.lazy + Suspense or dynamic import. Large route components.
    Virtualisation Render only visible rows in long lists. Lists over a few hundred items.
    Concurrent features useTransition, useDeferredValue. Slow, non-urgent updates.
    Profiler React DevTools Profiler. Before optimising anything.
  5. Advantages:
    • Faster, smoother UIs: Less wasted work.
    • Smaller initial bundle: Code splitting loads only what's needed.
    • Usable large lists: Virtualisation keeps FPS high.
    • Profiler shows targets: Precise optimisation, not guesses.
    • Better mobile performance: Lower CPU and memory.
  6. Disadvantages:
    • Premature optimisation: Makes code harder to read.
    • Overusing memoisation: Costs memory and CPU.
    • Wrong dependency arrays: Cause bugs and stale values.
    • Complexity for little gain: In small apps, optimisations rarely matter.
    • Extra code: More places to keep in sync.
  7. Characteristics:
    • Measure first: Use Profiler, do not guess.
    • Memoize only when measurable: If renders are cheap, don't bother.
    • Split at route boundaries: Default code splitting strategy.
    • Keep state close: Colocation reduces re-render scope.
    • Shallow trees: Less work per render pass.
  8. Diagram: Optimization workflow
    Profile app → identify slow component
            │
            ▼
    Is it re-rendering too often? ── yes → React.memo / useCallback
            │
            no
            ▼
    Is a computation heavy? ──────── yes → useMemo
            │
            no
            ▼
    Is the bundle too large? ─────── yes → React.lazy + code splitting
            │
            no
            ▼
    Is the list huge? ────────────── yes → virtualization
            │
            no
            ▼
    Re-profile and verify improvement
  9. Conclusion: Optimisation is measurement-driven. Start with the Profiler, fix only real problems, and re-measure. Memoization and code splitting are powerful but not free — use them where they matter. Good architecture (small state, shallow trees, colocated state) usually beats micro-optimisation. Aim for perceived performance (fast interactions) rather than absolute numbers.
  10. Exercise:
    1. Build a list of 1,000 items and profile it.
    2. Add React.memo to a row component and measure the improvement.
    3. Add route-level code splitting with React.lazy.
    4. Virtualize the list and compare memory and FPS.
    5. Use useTransition for a slow search filter.

हिंदी (सरल)

  1. समस्या: React हर state या props बदलाव पर components re-render करता है। बड़े apps में unnecessary renders sluggish UIs, dropped frames और high CPU का कारण बनते हैं। Measure किए बिना developers अक्सर गलत चीज़ optimize करते हैं या बिना लाभ complexity बढ़ाते हैं। बड़े JavaScript bundles first paint धीमा करते हैं।
  2. परिभाषा: React में performance optimization unnecessary काम कम करने का अभ्यास है: re-renders, महँगी computations और bundle size। मुख्य tools: React.memo, useMemo, useCallback, React.lazy + Suspense, virtualisation, और React DevTools Profiler।
  3. उदाहरण: Heavy child और stable callback को memoize करना:
    const MemoChild = React.memo(function Child({ value, onClick }) {
      return <button onClick={onClick}>{value}</button>;
    });
    
    function Parent({ data, id }) {
      const handleClick = useCallback(() => doSomething(id), [id]);
      const result = useMemo(() => expensiveCalc(data), [data]);
    
      return <MemoChild value={result} onClick={handleClick} />;
    }
  4. प्रकार:
    तकनीक उद्देश्य कब Use करें
    React.memo Props unchanged होने पर re-render skip करें। Child same props से re-render।
    useMemo महँगी computed value cache करें। Render में heavy computation।
    useCallback Function reference cache करें। Memoized child को stable callback चाहिए।
    Code splitting React.lazy + Suspense या dynamic import। बड़े route components।
    Virtualisation लंबी lists में सिर्फ visible rows render करें। कुछ सौ से ज़्यादा items वाली lists।
    Concurrent features useTransition, useDeferredValue। Slow, non-urgent updates।
    Profiler React DevTools Profiler। Optimize करने से पहले।
  5. लाभ:
    • तेज़, smooth UIs: कम wasted काम।
    • छोटा initial bundle: Code splitting से सिर्फ ज़रूरी load।
    • बड़ी lists usable: Virtualisation से FPS ऊँचा।
    • Profiler targets दिखाता है: Guessing नहीं, precise optimisation।
    • बेहतर mobile performance: कम CPU और memory।
  6. नुकसान:
    • समय से पहले optimization: Code पढ़ना मुश्किल।
    • Memoisation का अत्यधिक उपयोग: Memory और CPU cost।
    • गलत dependency arrays: Bugs और stale values।
    • छोटे apps में बेकार complexity: Optimisations rarely matter।
    • Extra code: Sync रखने की और जगह।
  7. विशेषताएँ:
    • पहले measure करें: Profiler use करें, guess न करें।
    • सिर्फ measurable हो तो memoize: Renders सस्ते हों तो न करें।
    • Route boundaries पर split: Default code splitting strategy।
    • State पास रखें: Colocation re-render scope घटाता है।
    • Shallow trees: हर render pass में कम काम।
  8. आरेख: Optimization workflow
    App profile करें → slow component पहचानें
            │
            ▼
    बहुत ज़्यादा re-render? ── हाँ → React.memo / useCallback
            │
            नहीं
            ▼
    Computation महँगी? ──────── हाँ → useMemo
            │
            नहीं
            ▼
    Bundle बड़ा? ───────────── हाँ → React.lazy + code splitting
            │
            नहीं
            ▼
    List बहुत बड़ी? ────────── हाँ → virtualization
            │
            नहीं
            ▼
    फिर profile करें और सुधार verify करें
  9. निष्कर्ष: Optimization measurement-driven है। Profiler से शुरू करें, सिर्फ असली problems fix करें, और फिर measure करें। Memoization और code splitting powerful हैं पर मुफ्त नहीं — जहाँ मायने रखें वहीं use करें। अच्छी architecture (छोटी state, shallow trees, colocated state) अक्सर micro-optimisation से बेहतर होती है। Perceived performance (तेज़ interactions) को absolute numbers से ज़्यादा महत्व दें।
  10. अभ्यास:
    1. 1,000 items की list बनाकर profile कीजिए।
    2. Row component में React.memo जोड़कर सुधार measure कीजिए।
    3. React.lazy से route-level code splitting जोड़िए।
    4. List virtualize करके memory और FPS की तुलना कीजिए।
    5. Slow search filter के लिए useTransition use कीजिए।

13. Testing React Apps – Jest, React Testing Library, MSW, Cypress

English

  1. Problem: React apps have many moving parts: components, state, effects, network calls, and user interactions. Bugs slip through manual testing, and refactors become scary without confidence. There is a need for fast, reliable automated tests that catch regressions before they ship.
  2. Definition: Testing React apps means verifying components and behaviours automatically. Unit tests check small units; integration tests check several components together; end-to-end tests drive the real app in a browser. Common tools: Jest, React Testing Library (RTL), Vitest, MSW (network mocking), Cypress, Playwright.
  3. Example: Testing a button with React Testing Library:
    import { render, screen, fireEvent } from '@testing-library/react';
    import LikeButton from './LikeButton';
    
    test('increments count on click', () => {
      render(<LikeButton />);
    
      expect(screen.getByText(/Likes: 0/)).toBeInTheDocument();
      fireEvent.click(screen.getByRole('button'));
      expect(screen.getByText(/Likes: 1/)).toBeInTheDocument();
    });
    
    test('renders custom initial label', () => {
      render(<LikeButton label="Hearts" />);
      expect(screen.getByText(/Hearts: 0/)).toBeInTheDocument();
    });
  4. Types:
    Type Scope Tools
    Unit Single function, hook, or component in isolation. Jest, Vitest
    Component / Integration Several components with user interactions. React Testing Library
    API mocking Simulate network responses. MSW, jest.mock
    End-to-end Real browser, real user flows. Cypress, Playwright
    Visual regression Screenshot comparisons. Percy, Chromatic
  5. Advantages:
    • Confidence when refactoring: Tests catch regressions.
    • Faster feedback: Than manual QA.
    • Living documentation: Tests describe expected behaviour.
    • E2E catches real bugs: Integration issues surface in browsers.
    • Better design: Testable code tends to be well-structured.
  6. Disadvantages:
    • Setup cost: Tooling, mocks, and CI take time.
    • Brittle tests: Slow the team down.
    • Implementation details: Testing them causes false failures.
    • E2E slow and flaky: Hard to maintain at scale.
    • Over-testing: 100% coverage is not the goal.
  7. Characteristics:
    • Test behaviour, not implementation: User-facing outcomes.
    • Query the DOM like a user: roles, labels, text.
    • Mock at the network layer: MSW gives realistic tests.
    • Follow the testing pyramid: Many unit, some integration, few E2E.
    • Fast feedback loops: Keep tests under a few seconds when possible.
  8. Diagram: Testing pyramid
             ▲        Few E2E tests (Cypress/Playwright)
            ╱ ╲
           ╱   ╲      Some integration tests (RTL)
          ╱─────╲
         ╱       ╲    Many unit tests (Jest/Vitest)
        ╱─────────╲
    
    MSW flow:
    
      Component → fetch('/api/users')
                        │
                        ▼
                 MSW intercepts
                        │
                        ▼
                 Returns mock JSON
                        │
                        ▼
                 Component renders data
  9. Conclusion: A healthy test suite mixes fast unit tests, realistic component tests, and a few E2E tests for critical flows. Use React Testing Library to test what users see and do, and MSW for network mocking. Aim for confidence, not 100% coverage. Invest in CI so tests run on every push. Delete or rewrite flaky tests rather than ignoring them.
  10. Exercise:
    1. Write a unit test for a utility function.
    2. Write a component test for a form with validation.
    3. Mock an API with MSW and test the loading → success flow.
    4. Write one Cypress test for the login flow.
    5. Add a Jest test for a custom hook using renderHook.

हिंदी (सरल)

  1. समस्या: React apps में कई चलते-फिरते हिस्से होते हैं: components, state, effects, network calls और user interactions। Manual testing से bugs निकल जाते हैं, और बिना confidence के refactoring डरावना हो जाता है। तेज़, विश्वसनीय automated tests चाहिए जो ship होने से पहले regressions पकड़ें।
  2. परिभाषा: React apps की testing का मतलब components और behaviours को automatically verify करना। Unit tests छोटी units जाँचते हैं; integration tests कई components एक साथ; end-to-end tests असली browser में पूरा app चलाते हैं। मुख्य tools: Jest, React Testing Library (RTL), Vitest, MSW (network mocking), Cypress, Playwright।
  3. उदाहरण: React Testing Library से button test:
    import { render, screen, fireEvent } from '@testing-library/react';
    import LikeButton from './LikeButton';
    
    test('click पर count बढ़ता है', () => {
      render(<LikeButton />);
    
      expect(screen.getByText(/Likes: 0/)).toBeInTheDocument();
      fireEvent.click(screen.getByRole('button'));
      expect(screen.getByText(/Likes: 1/)).toBeInTheDocument();
    });
    
    test('custom initial label render करता है', () => {
      render(<LikeButton label="Hearts" />);
      expect(screen.getByText(/Hearts: 0/)).toBeInTheDocument();
    });
  4. प्रकार:
    प्रकार दायरा Tools
    Unit एक function, hook, या component अलग से। Jest, Vitest
    Component / Integration कई components user interactions के साथ। React Testing Library
    API mocking Network responses simulate करना। MSW, jest.mock
    End-to-end असली browser, असली user flows। Cypress, Playwright
    Visual regression Screenshot तुलना। Percy, Chromatic
  5. लाभ:
    • Refactoring में confidence: Tests regressions पकड़ते हैं।
    • तेज़ feedback: Manual QA से तेज़।
    • Living documentation: Tests expected behaviour बताते हैं।
    • E2E असली bugs पकड़ते हैं: Integration issues browser में सामने आते हैं।
    • बेहतर design: Testable code अच्छी तरह structured होता है।
  6. नुकसान:
    • Setup cost: Tooling, mocks और CI में समय।
    • Brittle tests: Team को धीमा करते हैं।
    • Implementation details: Test करने से false failures।
    • E2E धीमे और flaky: Scale पर maintain करना मुश्किल।
    • Over-testing: 100% coverage लक्ष्य नहीं।
  7. विशेषताएँ:
    • Behaviour test करें, implementation नहीं: User-facing outcomes।
    • DOM को user की तरह query करें: roles, labels, text।
    • Network layer पर mock करें: MSW से realistic tests।
    • Testing pyramid follow करें: कई unit, कुछ integration, कम E2E।
    • तेज़ feedback loops: जहाँ possible हो कुछ seconds के अंदर tests।
  8. आरेख: Testing pyramid
             ▲        कम E2E tests (Cypress/Playwright)
            ╱ ╲
           ╱   ╲      कुछ integration tests (RTL)
          ╱─────╲
         ╱       ╲    कई unit tests (Jest/Vitest)
        ╱─────────╲
    
    MSW flow:
    
      Component → fetch('/api/users')
                        │
                        ▼
                 MSW intercept करता है
                        │
                        ▼
                 Mock JSON return
                        │
                        ▼
                 Component data render करता है
  9. निष्कर्ष: स्वस्थ test suite में तेज़ unit tests, realistic component tests और critical flows के लिए कुछ E2E tests का मेल होता है। React Testing Library से वही test करें जो users देखते और करते हैं, और network mocking के लिए MSW use करें। 100% coverage नहीं, confidence लक्ष्य है। CI में invest करें ताकि हर push पर tests चलें। Flaky tests को ignore करने की जगह delete या rewrite करें।
  10. अभ्यास:
    1. एक utility function के लिए unit test लिखिए।
    2. Validation वाले form के लिए component test लिखिए।
    3. MSW से API mock करके loading → success flow test कीजिए।
    4. Login flow के लिए एक Cypress test लिखिए।
    5. renderHook से custom hook के लिए Jest test जोड़िए।

14. Advanced React – Server Components, SSR/SSG/ISR, Hydration, TypeScript

English

  1. Problem: Pure client-side React has real limits: slow first paint, poor SEO, and large JavaScript bundles. Large apps also suffer from TypeScript-free codebases and context performance problems. Advanced patterns are needed to build fast, safe, large-scale apps that load quickly on slow networks.
  2. Definition: Advanced React covers server-side techniques (SSR, SSG, ISR, React Server Components), hydration, TypeScript integration, context performance, and modern React features like Concurrent rendering, useTransition, and useDeferredValue.
  3. Example: React Server Component in Next.js App Router:
    // app/users/page.tsx (Server Component by default)
    async function UserList() {
      const users = await db.user.findMany(); // runs on server
      return (
        <ul>
          {users.map(u => <li key={u.id}>{u.name}</li>)}
        </ul>
      );
    }
    
    export default UserList;
    No JavaScript for this component is shipped to the browser — it runs entirely on the server.
  4. Types:
    Technique Description Best For
    SSR Render HTML per request on the server, then hydrate. Personalised, fresh content.
    SSG Pre-render HTML at build time. Content that rarely changes.
    ISR Static pages regenerated in the background. Large content sites, e-commerce.
    React Server Components (RSC) Components that run only on the server, no client JS. Data-heavy pages, reduced bundle.
    Hydration Attach React to server-rendered HTML on the client. Making SSR pages interactive.
    TypeScript Static types for props, state, and hooks. Large teams, big codebases.
    Concurrent features useTransition, useDeferredValue, Suspense. Keeping UI responsive during slow updates.
  5. Advantages:
    • Faster first paint: Users see content quickly.
    • Better SEO: Crawlers see full HTML.
    • Smaller client bundles: RSC keeps data fetching on the server.
    • TypeScript: Catches errors at compile time.
    • Concurrent features: Keep the UI responsive.
  6. Disadvantages:
    • More moving parts: Server, client, hydration all interact.
    • Hydration mismatches: Hard to debug.
    • Framework required: RSC needs Next.js or similar.
    • TypeScript setup: Extra tooling and learning curve.
    • Caching complexity: SSR requires careful cache strategy.
  7. Characteristics:
    • RSC is not a client feature: Needs a supporting bundler.
    • Hydration must match server HTML: Small differences cause bugs.
    • TypeScript plays well with React: Props, state, hooks all typed.
    • Concurrent rendering: Allows interruptible updates.
    • Streaming: Suspense boundaries stream HTML in chunks.
  8. Diagram: SSR + hydration flow
    Browser request
          │
          ▼
    Server renders HTML + data
          │
          ▼
    HTML sent to browser (visible fast)
          │
          ▼
    JS bundle downloaded
          │
          ▼
    React hydrates HTML → interactive
          │
          ▼
    Subsequent navigation is client-side
    
    RSC boundary:
    
      Server Component (no JS shipped)
           │
           ▼
      Client Component (interactive)
           │
           ▼
      Server Component inside (again no JS)
  9. Conclusion: Advanced React gives you the tools to build fast, safe apps at scale. Use a framework like Next.js or Remix for SSR/SSG/RSC, adopt TypeScript for large teams, and understand hydration and concurrent rendering to debug subtle issues. These skills separate hobby projects from production apps. Do not over-engineer small sites — reach for these techniques when performance and SEO actually matter.
  10. Exercise:
    1. Create a Next.js app and add one Server Component.
    2. Compare the initial HTML of a CSR page and an SSR page.
    3. Convert a small component to TypeScript with props types.
    4. Use useTransition for a slow search filter.
    5. Explain the difference between SSG and ISR with an example.

हिंदी (सरल)

  1. समस्या: Pure client-side React की असली सीमाएँ हैं: slow first paint, खराब SEO, और बड़े JavaScript bundles। बड़े apps में TypeScript-free codebases और context performance समस्याएँ भी होती हैं। तेज़, safe, बड़े-scale apps बनाने के लिए advanced patterns चाहिए जो slow networks पर भी जल्दी load हों।
  2. परिभाषा: Advanced React में server-side techniques (SSR, SSG, ISR, React Server Components), hydration, TypeScript integration, context performance, और modern React features जैसे Concurrent rendering, useTransition, और useDeferredValue शामिल हैं।
  3. उदाहरण: Next.js App Router में React Server Component:
    // app/users/page.tsx (डिफ़ॉल्ट रूप से Server Component)
    async function UserList() {
      const users = await db.user.findMany(); // server पर चलता है
      return (
        <ul>
          {users.map(u => <li key={u.id}>{u.name}</li>)}
        </ul>
      );
    }
    
    export default UserList;
    इस component का कोई JavaScript browser को नहीं भेजा जाता — यह पूरी तरह server पर चलता है।
  4. प्रकार:
    तकनीक विवरण सबसे अच्छा
    SSR प्रति request server पर HTML render, फिर hydrate। Personalised, fresh content।
    SSG Build time पर HTML pre-render। Content जो कम बदलता है।
    ISR Static pages background में regenerate। बड़े content sites, e-commerce।
    React Server Components (RSC) सिर्फ server पर चलने वाले components, कोई client JS नहीं। Data-heavy pages, कम bundle।
    Hydration Server-rendered HTML पर client में React attach करना। SSR pages को interactive बनाना।
    TypeScript Props, state और hooks के लिए static types। बड़ी teams, बड़े codebases।
    Concurrent features useTransition, useDeferredValue, Suspense। Slow updates के दौरान UI responsive रखना।
  5. लाभ:
    • तेज़ first paint: Users जल्दी content देखते हैं।
    • बेहतर SEO: Crawlers पूरा HTML देखते हैं।
    • छोटे client bundles: RSC data fetching server पर रखता है।
    • TypeScript: Compile time पर errors।
    • Concurrent features: UI responsive रहता है।
  6. नुकसान:
    • ज़्यादा moving parts: Server, client, hydration सब interact।
    • Hydration mismatches: Debug करना मुश्किल।
    • Framework चाहिए: RSC के लिए Next.js जैसा।
    • TypeScript setup: Extra tooling और learning curve।
    • Caching complexity: SSR में सावधान cache strategy।
  7. विशेषताएँ:
    • RSC client feature नहीं: Supporting bundler चाहिए।
    • Hydration server HTML से match: छोटे फर्क से bugs।
    • TypeScript React के साथ: Props, state, hooks सब typed।
    • Concurrent rendering: Interruptible updates।
    • Streaming: Suspense boundaries HTML chunks में stream करती हैं।
  8. आरेख: SSR + hydration flow
    Browser request
          │
          ▼
    Server HTML + data render करता है
          │
          ▼
    HTML browser को भेजा (जल्दी दिखता है)
          │
          ▼
    JS bundle download
          │
          ▼
    React HTML hydrate करता है → interactive
          │
          ▼
    आगे की navigation client-side
    
    RSC boundary:
    
      Server Component (कोई JS नहीं)
           │
           ▼
      Client Component (interactive)
           │
           ▼
      Server Component अंदर (फिर कोई JS नहीं)
  9. निष्कर्ष: Advanced React बड़े scale पर तेज़, safe apps बनाने के tools देता है। SSR/SSG/RSC के लिए Next.js या Remix जैसा framework use करें, बड़ी teams के लिए TypeScript अपनाएँ, और hydration व concurrent rendering समझें ताकि subtle issues debug कर सकें। ये skills hobby projects को production apps से अलग करती हैं। छोटी sites पर over-engineer न करें — जब performance और SEO वाकई मायने रखें तभी ये techniques अपनाएँ।
  10. अभ्यास:
    1. एक Next.js app बनाकर एक Server Component जोड़िए।
    2. CSR page और SSR page के initial HTML की तुलना कीजिए।
    3. एक छोटे component को props types के साथ TypeScript में बदलिए।
    4. Slow search filter के लिए useTransition use कीजिए।
    5. SSG और ISR का फर्क एक उदाहरण के साथ समझाइए।

15. Architecture & Best Practices – Folder Structure, Design Systems, Tooling

English

  1. Problem: Small apps work with any structure. Large apps break down without clear folder conventions, consistent component APIs, shared design tokens, code quality tooling, and predictable state management. Teams slow down as the codebase grows, and new developers take weeks to onboard.
  2. Definition: React architecture is the set of decisions about how to organise files, split responsibilities, share UI, manage state, and enforce quality. Best practices cover folder structure (feature-based), composition over inheritance, custom hook design, design systems, Storybook, ESLint/Prettier/TypeScript, environment variables, and deployment.
  3. Example: A feature-based folder structure:
    src/
    ├── features/
    │   ├── auth/
    │   │   ├── components/
    │   │   │   ├── LoginForm.tsx
    │   │   │   └── SignupForm.tsx
    │   │   ├── hooks/
    │   │   │   └── useAuth.ts
    │   │   ├── api.ts
    │   │   └── index.ts
    │   └── todos/
    │       ├── components/
    │       ├── hooks/
    │       └── api.ts
    ├── components/      # shared UI (Button, Modal)
    ├── hooks/           # shared hooks
    ├── lib/             # utilities
    ├── pages/ or app/   # routing entry points
    └── App.tsx
  4. Types:
    Area Best Practice Why
    Folder structure Feature-based with shared folders at top level. Predictable, scalable.
    Composition Composition over inheritance; props and children. Flexible, testable.
    Custom hooks One concern per hook; prefix with use. Reusable logic.
    Design system Storybook + tokens + shared components. Consistent UI.
    Tooling ESLint, Prettier, TypeScript, Husky pre-commit. Fewer bugs, uniform style.
    Environment .env with VITE_/NEXT_PUBLIC_ prefixes. Config without hardcoding.
    Deployment Vercel, Netlify, AWS, Docker + CI/CD. Repeatable, safe releases.
  5. Advantages:
    • Predictable structure: New devs onboard faster.
    • Smaller blast radius: Changes stay inside features.
    • Consistent UI: Design system keeps look and feel uniform.
    • Automated quality gates: Catch issues before code review.
    • Better collaboration: Conventions reduce friction.
  6. Disadvantages:
    • Setup effort: Tooling and Storybook take time.
    • Rigid conventions: Can slow prototyping.
    • Design system maintenance: Requires ongoing care.
    • Too many shared components: Cause coupling.
    • Overhead for small teams: Process can feel heavy.
  7. Characteristics:
    • Feature folders own their stuff: Components, hooks, API calls together.
    • Shared components are minimal: Generic and reusable.
    • Public APIs via index.ts: Barrel exports.
    • Consistent naming: PascalCase components, camelCase hooks.
    • TypeScript everywhere: Types catch bugs early.
    • Environment separation: .env.development, .env.production.
  8. Diagram: Layered architecture
    ┌──────────────────────────────────┐
    │  app/  (routing, providers)      │
    ├──────────────────────────────────┤
    │  features/  (auth, todos, cart)  │
    ├──────────────────────────────────┤
    │  components/  (Button, Modal)    │
    ├──────────────────────────────────┤
    │  hooks/  lib/  (shared logic)    │
    ├──────────────────────────────────┤
    │  services/ api/  (network)       │
    └──────────────────────────────────┘
    
    Dependency rule: outer layers import
    from inner layers, not the reverse.
  9. Conclusion: Good architecture is about making the right thing easy and the wrong thing hard. Feature folders, composition, design systems, and tooling all contribute. Adopt what your team will actually maintain; start small and grow the conventions as the app grows. Beware of over-engineering — clarity beats cleverness every time. Document decisions in a README so future contributors understand the why.
  10. Exercise:
    1. Refactor a small app into a feature-based folder structure.
    2. Create three shared components and document them in Storybook.
    3. Set up ESLint + Prettier + TypeScript in a Vite React project.
    4. Add a pre-commit hook with Husky and lint-staged.
    5. Write a short README explaining your folder structure.

हिंदी (सरल)

  1. समस्या: छोटे apps किसी भी structure से चलते हैं। बड़े apps बिना स्पष्ट folder conventions, consistent component APIs, shared design tokens, code quality tooling और predictable state management के टूट जाते हैं। Codebase बढ़ने पर teams धीमी हो जाती हैं, और नए developers को onboard होने में हफ्ते लग जाते हैं।
  2. परिभाषा: React architecture यह तय करने का सेट है कि files कैसे organise करें, responsibilities कैसे बाँटें, UI कैसे share करें, state कैसे manage करें और quality कैसे enforce करें। Best practices में folder structure (feature-based), composition over inheritance, custom hook design, design systems, Storybook, ESLint/Prettier/TypeScript, environment variables और deployment शामिल हैं।
  3. उदाहरण: Feature-based folder structure:
    src/
    ├── features/
    │   ├── auth/
    │   │   ├── components/
    │   │   │   ├── LoginForm.tsx
    │   │   │   └── SignupForm.tsx
    │   │   ├── hooks/
    │   │   │   └── useAuth.ts
    │   │   ├── api.ts
    │   │   └── index.ts
    │   └── todos/
    │       ├── components/
    │       ├── hooks/
    │       └── api.ts
    ├── components/      # साझा UI (Button, Modal)
    ├── hooks/           # साझा hooks
    ├── lib/             # utilities
    ├── pages/ या app/   # routing entry points
    └── App.tsx
  4. प्रकार:
    क्षेत्र Best Practice क्यों
    Folder structure Feature-based, top level पर shared folders। Predictable, scalable।
    Composition Inheritance की जगह composition; props और children। Flexible, testable।
    Custom hooks एक hook एक concern; use से शुरू। Reusable logic।
    Design system Storybook + tokens + shared components। Consistent UI।
    Tooling ESLint, Prettier, TypeScript, Husky pre-commit। कम bugs, uniform style।
    Environment .env with VITE_/NEXT_PUBLIC_ prefixes। Config बिना hardcode।
    Deployment Vercel, Netlify, AWS, Docker + CI/CD। Repeatable, safe releases।
  5. लाभ:
    • Predictable structure: नए devs जल्दी onboard।
    • छोटा blast radius: बदलाव features के अंदर रहते हैं।
    • Consistent UI: Design system से look and feel uniform।
    • Automated quality gates: Code review से पहले issues।
    • बेहतर collaboration: Conventions friction घटाती हैं।
  6. नुकसान:
    • Setup effort: Tooling और Storybook में समय।
    • Rigid conventions: Prototyping धीमा कर सकती हैं।
    • Design system maintenance: लगातार देखभाल चाहिए।
    • बहुत ज़्यादा shared components: Coupling बढ़ाते हैं।
    • छोटी teams पर overhead: Process भारी लग सकता है।
  7. विशेषताएँ:
    • Feature folders अपना सब कुछ रखते हैं: Components, hooks, API calls साथ।
    • Shared components minimal: Generic और reusable।
    • Public APIs index.ts से: Barrel exports।
    • Consistent naming: PascalCase components, camelCase hooks।
    • TypeScript हर जगह: Types bugs जल्दी पकड़ते हैं।
    • Environment separation: .env.development, .env.production।
  8. आरेख: Layered architecture
    ┌──────────────────────────────────┐
    │  app/  (routing, providers)      │
    ├──────────────────────────────────┤
    │  features/  (auth, todos, cart)  │
    ├──────────────────────────────────┤
    │  components/  (Button, Modal)    │
    ├──────────────────────────────────┤
    │  hooks/  lib/  (shared logic)    │
    ├──────────────────────────────────┤
    │  services/ api/  (network)       │
    └──────────────────────────────────┘
    
    Dependency rule: outer layers inner
    layers से import करें, उल्टा नहीं।
  9. निष्कर्ष: अच्छी architecture का मतलब सही चीज़ को आसान और गलत को मुश्किल बनाना है। Feature folders, composition, design systems और tooling सब योगदान देते हैं। जो आपकी team वाकई maintain करे वही अपनाएँ; छोटे से शुरू करें और app के साथ conventions बढ़ाएँ। Over-engineering से बचें — clarity हर बार cleverness से जीतती है। फैसलों को README में document करें ताकि future contributors को 'क्यों' समझ आए।
  10. अभ्यास:
    1. छोटे app को feature-based folder structure में refactor कीजिए।
    2. तीन shared components बनाकर Storybook में document कीजिए।
    3. Vite React project में ESLint + Prettier + TypeScript set up कीजिए।
    4. Husky और lint-staged से pre-commit hook जोड़िए।
    5. अपनी folder structure समझाने वाला छोटा README लिखिए।

16. Projects & Capstones – Practice Ideas and Full-Stack Checklist

English

  1. Problem: Watching tutorials is not the same as building real projects. Learners often freeze when facing an empty codebase because they never practiced combining components, state, routing, data fetching, testing, and deployment into one app. Without a strong project portfolio, it's hard to get hired or feel confident.
  2. Definition: Projects are hands-on applications that combine everything you learned. Capstones are larger, portfolio-ready apps that include auth, APIs, global state, server state, testing, and deployment.
  3. Example: Suggested capstone checklist:
    ✔ Auth (login / signup)
    ✔ REST or GraphQL API
    ✔ Global state (Redux Toolkit / Zustand)
    ✔ Server state (TanStack Query)
    ✔ Routing + protected routes
    ✔ Forms with validation
    ✔ Responsive UI (Tailwind / CSS Modules)
    ✔ Accessibility (keyboard, ARIA)
    ✔ Tests (Jest + RTL, one Cypress flow)
    ✔ CI/CD + deployment (Vercel / Netlify)
    ✔ README with screenshots and live link
  4. Types:
    Level Example Projects Focus Skills
    Beginner Todo app, Counter, Weather widget, Quiz app Components, state, effects
    Intermediate Movie search, Blog, Expense tracker, Kanban board, Notes with auth Routing, data fetching, forms
    Advanced E-commerce store, Chat app (WebSockets), Social feed, Admin dashboard, LMS Global state, real-time, performance
    Capstone Full-stack app with auth, API, tests, CI/CD, and deployment Everything combined
  5. Advantages:
    • Real understanding: Building teaches more than watching.
    • Portfolio: Projects impress employers and clients.
    • Bug exposure: You learn to debug real problems.
    • Architectural sense: Combining features reveals trade-offs.
    • Confidence: Shipping something real changes how you see yourself.
  6. Disadvantages:
    • Time-consuming: Real projects take weeks.
    • Overwhelming at first: The empty repo can freeze beginners.
    • Scope creep: Features grow beyond the plan.
    • Deployment friction: Env vars, DNS, and CI/CD add work.
    • Unfinished projects: Without focus, many stay half-done.
  7. Characteristics:
    • Start small, ship early: Iterate instead of over-planning.
    • One strong capstone beats five unfinished projects.
    • Write a README: Screenshots, features, tech stack, live link.
    • Deploy from day one: Practice the full loop.
    • Test the critical paths: Login, checkout, submit.
    • Keep a changelog: Show progress and thought process.
  8. Diagram: Project progression
    Beginner  ──► Todo / Weather / Quiz
            │
            ▼
    Intermediate ──► Movie search / Blog / Expense tracker
            │
            ▼
    Advanced  ──► E-commerce / Chat / Admin dashboard
            │
            ▼
    Capstone  ──► Full-stack + Auth + Tests + CI/CD + Deploy
    
    Suggested timeline for a capstone:
    
      Week 1: Setup + Auth + basic routing
      Week 2: Core features + API integration
      Week 3: Polish UI + tests + accessibility
      Week 4: Deploy + README + demo video
  9. Conclusion: The fastest way to become a confident React developer is to build. Finish small projects, then tackle one strong capstone that demonstrates everything you know. Deploy it, write about it, and keep iterating. Your portfolio is the strongest signal you can send to employers. Focus on depth — one polished project beats many shallow ones. Document your decisions; future you will thank present you.
  10. Exercise:
    1. Build a Todo app with localStorage persistence.
    2. Build a Movie search app using a public API and TanStack Query.
    3. Build an Expense tracker with charts and Zustand.
    4. Build a capstone: full-stack app with auth, API, tests, and deployment.
    5. Write a README with screenshots and a live link.
    6. Record a short demo video and post it on your portfolio.

हिंदी (सरल)

  1. समस्या: Tutorials देखना और असली projects बनाना एक नहीं है। शुरुआती लोग खाली codebase देखकर अक्सर freeze हो जाते हैं क्योंकि उन्होंने कभी components, state, routing, data fetching, testing और deployment को एक app में combine करके practice नहीं की। मजबूत project portfolio के बिना नौकरी पाना या confident महसूस करना मुश्किल है।
  2. परिभाषा: Projects hands-on applications हैं जो सीखी हुई सब चीज़ों को जोड़ते हैं। Capstones बड़े, portfolio-ready apps हैं जिनमें auth, APIs, global state, server state, testing और deployment शामिल होते हैं।
  3. उदाहरण: Capstone checklist का सुझाव:
    ✔ Auth (login / signup)
    ✔ REST या GraphQL API
    ✔ Global state (Redux Toolkit / Zustand)
    ✔ Server state (TanStack Query)
    ✔ Routing + protected routes
    ✔ Validation वाले forms
    ✔ Responsive UI (Tailwind / CSS Modules)
    ✔ Accessibility (keyboard, ARIA)
    ✔ Tests (Jest + RTL, एक Cypress flow)
    ✔ CI/CD + deployment (Vercel / Netlify)
    ✔ Screenshots और live link वाला README
  4. प्रकार:
    स्तर उदाहरण Projects Focus Skills
    Beginner Todo app, Counter, Weather widget, Quiz app Components, state, effects
    Intermediate Movie search, Blog, Expense tracker, Kanban board, auth वाला Notes Routing, data fetching, forms
    Advanced E-commerce store, Chat app (WebSockets), Social feed, Admin dashboard, LMS Global state, real-time, performance
    Capstone auth, API, tests, CI/CD और deployment वाला full-stack app सब कुछ combined
  5. लाभ:
    • असली समझ: बनाना सिखाता है, देखना नहीं।
    • Portfolio: Projects employers और clients को impress करते हैं।
    • Bug exposure: असली problems debug करना सीखते हैं।
    • Architectural sense: Features combine करने से trade-offs समझ आते हैं।
    • Confidence: कुछ असली ship करने से खुद को देखने का नज़रिया बदलता है।
  6. नुकसान:
    • समय लेने वाला: असली projects में हफ्ते लगते हैं।
    • शुरू में overwhelming: खाली repo beginners को freeze कर देता है।
    • Scope creep: Features plan से बाहर बढ़ते हैं।
    • Deployment friction: Env vars, DNS और CI/CD extra काम।
    • अधूरे projects: Focus के बिना कई आधे रह जाते हैं।
  7. विशेषताएँ:
    • छोटे से शुरू करें, जल्दी ship करें: Over-planning की जगह iterate करें।
    • एक मजबूत capstone पाँच अधूरे projects से बेहतर।
    • README लिखें: Screenshots, features, tech stack, live link।
    • पहले दिन से deploy करें: पूरा loop practice।
    • Critical paths test करें: Login, checkout, submit।
    • Changelog रखें: Progress और सोच दिखाएँ।
  8. आरेख: Project progression
    Beginner  ──► Todo / Weather / Quiz
            │
            ▼
    Intermediate ──► Movie search / Blog / Expense tracker
            │
            ▼
    Advanced  ──► E-commerce / Chat / Admin dashboard
            │
            ▼
    Capstone  ──► Full-stack + Auth + Tests + CI/CD + Deploy
    
    Capstone के लिए सुझाया timeline:
    
      Week 1: Setup + Auth + basic routing
      Week 2: Core features + API integration
      Week 3: UI polish + tests + accessibility
      Week 4: Deploy + README + demo video
  9. निष्कर्ष: Confident React developer बनने का सबसे तेज़ तरीका बनाना है। छोटे projects finish करें, फिर एक मजबूत capstone बनाएँ जो आपकी सारी जानकारी दिखाए। उसे deploy करें, उसके बारे में लिखें, और iterate करते रहें। आपका portfolio employers को सबसे मजबूत signal है। Depth पर focus करें — एक polished project कई shallow projects से बेहतर है। अपने decisions document करें; future आप मौजूदा आप को धन्यवाद देगा।
  10. अभ्यास:
    1. localStorage persistence वाला Todo app बनाइए।
    2. Public API और TanStack Query से Movie search app बनाइए।
    3. Charts और Zustand वाला Expense tracker बनाइए।
    4. Capstone बनाइए: auth, API, tests और deployment वाला full-stack app।
    5. Screenshots और live link के साथ README लिखिए।
    6. छोटा demo video record करके अपने portfolio पर post कीजिए।