Skip to content
beginnerPhase 36 · React

useState

Master the useState hook for local component state management.

45m
0 problems
Topic Progress0%

Basic Usage

Basic Usage

Syntax

const [state, setState] = useState(initialValue);
  • state: Current state value
  • setState: Function to update state
  • initialValue: Initial state value

Simple Example

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(count - 1)}>Decrement</button>
    </div>
  );
}

String State

function NameInput() {
  const [name, setName] = useState("");

  return (
    <div>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <p>Hello, {name || "Stranger"}!</p>
    </div>
  );
}

Boolean State

function Toggle() {
  const [isOn, setIsOn] = useState(false);

  return (
    <div>
      <button onClick={() => setIsOn(!isOn)}>
        {isOn ? "ON" : "OFF"}
      </button>
    </div>
  );
}

Object State

function UserForm() {
  const [user, setUser] = useState({
    name: "",
    email: "",
    age: 0
  });

  const updateField = (field, value) => {
    setUser((prev) => ({ ...prev, [field]: value }));
  };

  return (
    <form>
      <input
        value={user.name}
        onChange={(e) => updateField("name", e.target.value)}
      />
      <input
        value={user.email}
        onChange={(e) => updateField("email", e.target.value)}
      />
    </form>
  );
}

Lazy Initialization

Lazy Initialization

The Problem

// Bad: Expensive computation on every render
function ExpensiveComponent() {
  const [data, setData] = useState(computeExpensiveValue()); // Runs every render
}

The Solution

// Good: Lazy initialization - only runs once
function ExpensiveComponent() {
  const [data, setData] = useState(() => computeExpensiveValue());
}

When to Use

  • Expensive computations
  • Large data structures
  • Reading from localStorage
  • Initializing complex objects

Examples

// localStorage
function App() {
  const [theme, setTheme] = useState(() => {
    return localStorage.getItem("theme") || "light";
  });
}

// Complex calculation
function App() {
  const [fibonacci, setFibonacci] = useState(() => {
    return calculateFibonacci(100);
  });
}

// Large array
function App() {
  const [items, setItems] = useState(() => {
    return generateLargeArray(10000);
  });
}

Functional Updates

Functional Updates

The Problem

function Counter() {
  const [count, setCount] = useState(0);

  const incrementThree = () => {
    setCount(count + 1);
    setCount(count + 1);
    setCount(count + 1);
    // Only adds 1! count is still 0 in all three calls
  };
}

The Solution

function Counter() {
  const [count, setCount] = useState(0);

  const incrementThree = () => {
    setCount((prev) => prev + 1);
    setCount((prev) => prev + 1);
    setCount((prev) => prev + 1);
    // Adds 3! Each update uses the latest value
  };
}

When to Use

  • New state depends on old state
  • Multiple updates in same handler
  • Avoiding stale closures

Examples

// Toggle
const toggle = () => setOn((prev) => !prev);

// Increment
const increment = () => setCount((prev) => prev + 1);

// Add to array
const addItem = (item) => setItems((prev) => [...prev, item]);

// Remove from array
const removeItem = (id) => setItems((prev) => prev.filter((item) => item.id !== id));

// Update object
const updateUser = (updates) => setUser((prev) => ({ ...prev, ...updates }));

Practice Problems

0/3solved
Build useState Component

Create a reusable React component implementing useState. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
useState Testing

Write unit and integration tests for useState using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
useState Performance

Optimize useState for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. What does useState return?

Question 1 options

2. When should you use lazy initialization?

Question 2 options

3. What is a functional update?

Question 3 options

4. Why use functional updates?

Question 4 options

Flashcards

Question

What does useState return?

Answer

An array with [state, setState]

Question

What is lazy initialization?

Answer

Passing a function to useState that computes the initial value

Question

When to use functional updates?

Answer

When new state depends on old state

Question

How do you update object state?

Answer

Spread previous state and override: { ...prev, field: value }

Question

What is useState?

Answer

useState is a key concept in frontend development.

Revision Notes

Key Takeaways

  • 1.useState returns [state, setState]
  • 2.Use lazy initialization for expensive computations
  • 3.Use functional updates when new state depends on old
  • 4.Always create new objects/arrays for state updates
  • 5.Multiple setStates in same handler are batched

Interview Tips

  • Explain lazy initialization vs immediate initialization
  • Show functional update patterns
  • Demonstrate immutable state updates

Cheat Sheet

Cheat Sheet

Basic Usage

const [count, setCount] = useState(0);
setCount(count + 1);

Lazy Initialization

const [data, setData] = useState(() => expensiveCalc());

Functional Update

setCount(prev => prev + 1);

Object State

const [user, setUser] = useState({ name: "", age: 0 });
setUser(prev => ({ ...prev, name: "Alice" }));

Array State

const [items, setItems] = useState([]);
setItems(prev => [...prev, newItem]);
setItems(prev => prev.filter(i => i.id !== id));