useState and reactivity

useState gives you a value and a function to change it. When you call the setter, React re-renders the component with the new value. That is the whole reactivity model. No observers, no subscriptions, no getters and setters. Just functions.

Counter.tsx
tsx
import { useState } from 'react';

export 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>
    </div>
  );
}

The smallest useful example of useState.

One rule that catches everyone at first. Never mutate state directly. setCount(count + 1) is correct. count++ is wrong. Even for objects and arrays, always create a new copy with a spread or a map. React compares state by reference to decide whether to re-render. Mutation breaks that comparison and your UI stops updating.

Quiz: Quiz

Loading practice…