← Back to React Course | Chapter 4: State & Event Handling | Lesson 1 of 10

Introduction to useState

useState is a magic box that lets a component remember a value and redraw itself whenever that value changes.

Creating State with useState

useState(initialValue) returns an array with two items: the current state value, and a function to update it. By convention, you destructure these into two variables using array destructuring, typically named value and setValue.

Note: Name the setter function set followed by the state variable name, like count/setCount, for consistency.

Warning: useState must be called at the top level of the component, never inside an if statement, loop, or nested function.

Example: Creating State with useState

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    function Counter() {
      const [count, setCount] = React.useState(0);
      return <p>Count: {count}</p>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<Counter />);
  </script>
</body>
</html>

Updating State to Trigger a Re-render

Calling the setter function updates the state value AND tells React to re-render the component with the new value. This is what makes the UI actually change in response to user actions like clicks.

Note: Always use the setter function to change state -- never assign directly to the state variable.

Warning: Assigning directly (like count = count + 1) does NOT trigger a re-render and the UI won't update.

Example: Updating State to Trigger a Re-render

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    function Counter() {
      const [count, setCount] = React.useState(0);
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={() => setCount(count + 1)}>Increment</button>
        </div>
      );
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<Counter />);
  </script>
</body>
</html>

Each Component Has Its Own State

When you use the same component multiple times, each instance gets its own independent state -- changing one doesn't affect the others. This is because useState is tied to each individual rendered component instance, not shared globally.

Note: This independence is what makes components reusable -- you can drop the same stateful component anywhere without it interfering with other copies.

Warning: Beginners sometimes expect state to be shared across all instances of a component by default -- it is not, unless you explicitly lift it up.

Example: Each Component Has Its Own State

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    function Counter() {
      const [count, setCount] = React.useState(0);
      return <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>;
    }
    function App() {
      return <div><Counter /><Counter /></div>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>
Common Mistakes
  1. Calling useState inside a loop, condition, or nested function instead of at the top level of the component.
  2. Directly mutating the state variable instead of calling its setter function.
  3. Expecting the state variable to update immediately after calling the setter within the same function call.
Chapter Summary
  • useState is a Hook that adds state to a function component.
  • It returns a pair: the current value and a function to update it.
  • Calling the setter triggers a re-render with the new value.
  • State updates are not applied synchronously within the same function call.
Browser Support

Available since React 16.8, when Hooks were introduced.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.