Lesson 6 of 20

State with useState

Managing State with useState

State is data that changes over time in your component. When state changes, React re-renders the component to reflect the new data. The useState hook lets you add state to functional components.

useState returns an array with two elements: the current state value and a function to update it. By convention, we use array destructuring to name them.

Example
import { useState } from 'react';

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

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
      <button onClick={() => setCount(0)}>Reset</button>
    </div>
  );
}
  • useState(initialValue) — Creates a state variable with an initial value
  • Returns [value, setValue] — The current value and an updater function
  • Calling setValue triggers a re-render of the component
  • State is local to each component instance
  • You can use multiple useState calls for different pieces of state
Notes
  • Never modify state directly (count++ or count = 5). Always use the setter function (setCount) to update state.

State with Objects and Arrays

When state is an object or array, you must create a new copy when updating — never mutate the existing state. Use the spread operator (...) to create copies.

Example
function UserForm() {
  const [user, setUser] = useState({
    name: '',
    email: ''
  });

  const [items, setItems] = useState(['Apple', 'Banana']);

  // Update object state (spread to copy)
  function updateName(e) {
    setUser({ ...user, name: e.target.value });
  }

  // Add to array state (spread to copy)
  function addItem(item) {
    setItems([...items, item]);
  }

  // Remove from array state (filter creates a new array)
  function removeItem(index) {
    setItems(items.filter((_, i) => i !== index));
  }

  return (
    <div>
      <input value={user.name} onChange={updateName} />
      <ul>
        {items.map((item, i) => (
          <li key={i}>{item}</li>
        ))}
      </ul>
    </div>
  );
}
Notes
  • Always treat state as immutable. Use spread (...), map(), filter(), and slice() to create new copies when updating objects and arrays.