Courses/React/State and Lifecycle

    Lesson 3 • Beginner

    State and Lifecycle ⚛️

    Make your components dynamic! Learn useState for managing changing data and useEffect for handling side effects like data fetching and subscriptions.

    What You'll Learn in This Lesson

    • • The useState hook for managing component data
    • • Updating state with objects and arrays (immutably)
    • • The useEffect hook for side effects
    • • Dependency arrays and cleanup functions
    • • Building a practical todo list with state

    1️⃣ useState — The Basics

    useState is a React Hook that lets you add state to function components. It returns a pair: the current value and a function to update it. When you call the setter function, React re-renders the component with the new value.

    Try It: useState Basics

    Learn how state works and how to update it correctly

    Try it Yourself »
    JavaScript
    // useState — Making Components Dynamic
    console.log("=== What is State? ===");
    console.log("State is data that can CHANGE over time.");
    console.log("When state changes, React RE-RENDERS the component.");
    console.log();
    
    // Simulating useState
    console.log("=== useState Hook ===");
    console.log("import { useState } from 'react';");
    console.log();
    console.log("function Counter() {");
    console.log("  const [count, setCount] = useState(0);");
    console.log("  // count = current value");
    console.log("  //
    ...

    2️⃣ Complex State — Objects & Arrays

    State can hold any JavaScript value — strings, numbers, booleans, objects, or arrays. When updating objects or arrays, always create a new copy using the spread operator. Never mutate state directly!

    Try It: Objects & Arrays

    Manage complex state with objects and arrays

    Try it Yourself »
    JavaScript
    // Multiple State Variables
    console.log("=== Multiple useState Calls ===");
    console.log();
    
    let name = "";
    let email = "";
    let age = 0;
    let isSubscribed = false;
    
    console.log("function SignUpForm() {");
    console.log("  const [name, setName] = useState('');");
    console.log("  const [email, setEmail] = useState('');");
    console.log("  const [age, setAge] = useState(0);");
    console.log("  const [isSubscribed, setIsSubscribed] = useState(false);");
    console.log("}");
    console.log();
    
    // State with objects
    ...

    3️⃣ useEffect — Side Effects & Lifecycle

    useEffect lets you perform side effects — things that happen outside of rendering, like fetching data, setting up timers, or subscribing to events. The dependency array controls when the effect runs.

    Try It: useEffect

    Understand the component lifecycle and side effects

    Try it Yourself »
    JavaScript
    // Component Lifecycle with useEffect
    console.log("=== useEffect — Side Effects ===");
    console.log("useEffect runs code AFTER the component renders.");
    console.log();
    
    console.log("// Run on EVERY render:");
    console.log("useEffect(() => {");
    console.log("  console.log('Component rendered');");
    console.log("});");
    console.log();
    
    console.log("// Run ONCE on mount:");
    console.log("useEffect(() => {");
    console.log("  console.log('Component mounted');");
    console.log("  // Fetch data, set up subscrip
    ...

    4️⃣ Practical Example: Todo List

    Let's combine everything into a practical example. This todo list demonstrates adding, toggling, and removing items — all using immutable state updates.

    Try It: Todo List

    Build a complete todo list with state management

    Try it Yourself »
    JavaScript
    // Practical Example: Todo List State Management
    console.log("=== Building a Todo List ===");
    console.log();
    
    let todos = [];
    let nextId = 1;
    
    function addTodo(text) {
      todos = [...todos, { id: nextId++, text, completed: false }];
    }
    
    function toggleTodo(id) {
      todos = todos.map(todo =>
        todo.id === id ? { ...todo, completed: !todo.completed } : todo
      );
    }
    
    function removeTodo(id) {
      todos = todos.filter(todo => todo.id !== id);
    }
    
    // Simulate user actions
    addTodo("Learn useState");
    addTod
    ...

    ⚠️ Common Mistakes

    ⚠️
    Mutating state directlystate.push(item) won't trigger a re-render. Use setState([...state, item]).
    ⚠️
    Missing useEffect dependencies — Always include all variables used inside useEffect in the dependency array.
    💡
    Pro Tip: Use setState(prev => prev + 1) (functional update) when the new state depends on the previous state. This avoids stale closure bugs.

    📋 Quick Reference

    PatternSyntax
    useStateconst [val, setVal] = useState(initial)
    Functional updatesetCount(prev => prev + 1)
    Update objectsetObj({ ...obj, key: newVal })
    useEffect (mount)useEffect(() => {}, [])
    Cleanupreturn () => clearInterval(id)

    🎉 Lesson Complete!

    You now understand how to make components dynamic with state and handle side effects. Next, we'll learn how to handle user events!

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service