React useState: Your First Hook for Managing State

Learning React


React components often need to remember and change data - like a button click count, form input values, or whether a modal is open. React's useState hook makes this possible.

What is State?

State is data that can change over time in your component. When state changes, React automatically re-renders your component with the new values.

Think of state like a variable that React watches. When it changes, React updates what users see.

        
        
          
            
          
          
            
          
        

        // This won't work - regular variables don't trigger re-renders

function Counter() {

  let count = 0;
  
  const increment = () => {
    count = count + 1; // Changes the variable but doesn't update the UI
  };

  return <button onClick={increment}>{count}</button>; // Always shows 0

}
      

Your First useState Example:

        
        
          
            
          
          
            
          
        

        import { useState } from 'react';

function Counter() {

  // 1. Declaring the state variable: count holds the current value.
  // 2. useState takes as a parameter the initial value, in this case is 0.
  const [count, setCount] = useState(0);

  // 2. Creating the update function. setCount changes the state.
  const increment = () => {
    setCount(count + 1); // Updates state AND triggers re-render
  };

  return <button onClick={increment}>{count}</button>; // Shows current count

}
      

The useState pattern

The naming pattern is [value, setValue] - you can name them anything:

        
        
          
            
          
          
            
          
        

        // Setting a name as state variable, initial value is an empty string
const [name, setName] = useState('');

// Setting a isOpen flag as a state variable, initial value is false
const [isOpen, setIsOpen] = useState(false);

// Setting items as a state variable, initial value is an empty array
const [items, setItems] = useState([]);
      

Practical Examples

An Input field

        
        
          
            
          
          
            
          
        

        import { useState} from 'react';

export default function NameForm() {
  
  const [name, setName] = useState('');  

  return (
    <div>
      <input 
      value={name} 
      onChange={(e) => setName(e.target.value)}
      placeholder="Enter your name"
      />
      <p>Hello, {name}!</p>    
    </div>
  );

}
      

A Toggle button

        
        
          
            
          
          
            
          
        

        import { useState} from 'react';

export default function ToggleButton() {

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

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

}
      

Shopping List

        
        
          
            
          
          
            
          
        

        import { useState} from 'react';

export default function ShoppingList() {

  const [items, setItems] = useState([]);
  const [newItem, setNewItem] = useState('');
  
  const addItem = () => {
    setItems([...items, newItem]);
    setNewItem('');
  };

  return (
    <div>
      <input 
        value={newItem}
        onChange={(e) => setNewItem(e.target.value)}
        placeholder="Add item"
      />
      <button onClick={addItem}>Add</button>
      <ul>
        {items.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );

}
      

Important Rules

1. State updates are asynchronous: React batches state updates for performance. The new value isn't available immediately after calling the setter.

        
        
          
            
          
          
            
          
        

        const handleClick = () => {
  setCount(count + 1);
  console.log(count); // Still shows the old value
};
      

2. Don't mutate state directly: Always use the setter function. React won't detect changes to objects or arrays if you modify them directly.

        
        
          
            
          
          
            
          
        

        // Wrong - mutating directly
const addItem = () => {
  items.push(newItem); // React won't detect this change
  setItems(items);
};

// Right - creating new array
const addItem = () => {
  setItems([...items, newItem]); // React detects this change
};
      

3. Initial state only runs once: The value you pass to useState is only used on the first render.

        
        
          
            
          
          
            
          
        

         const [count, setCount] = useState(Math.random()); // Only calculated once
      

When to Use State

Use useState when:

  • Data changes in response to user actions
  • You need to show different content based on conditions
  • Values need to persist between renders
  • You're handling form inputs

Don't use state for:

  • Values that never change
  • Data that can be calculated from other state
  • Values only used during a single render

State is the foundation of interactive React applications. Master useState and you'll be able to build dynamic, responsive user interfaces.

Now that you understand basic state management, you're ready to learn about more advanced patterns like functional updates, which help avoid common bugs when updating state based on previous values.