Dung (Donny) Nguyen

Senior Software Engineer

Overview of useState in React.js

useState is a React Hook that lets you add state to functional components. Before Hooks, only class components could hold and manage local state. With useState, function components can store values that persist across renders and trigger a re-render whenever those values change.

How useState Works

Syntax

const [state, setState] = useState(initialValue);

Basic Example

import { useState } from 'react';

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

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Each time the button is clicked, setCount updates the state and React re-renders the component with the new count.

Updating State Based on Previous State

When the new state depends on the previous state, pass an updater function to avoid stale values, especially when multiple updates happen together:

setCount(prevCount => prevCount + 1);

This is safer than setCount(count + 1) because React guarantees prevCount holds the most recent state.

Lazy Initial State

If computing the initial state is expensive, pass a function to useState. React will call it only once, on the initial render:

const [value, setValue] = useState(() => expensiveComputation());

Working with Objects and Arrays

State updates replace the value rather than merge it. When your state is an object or array, spread the existing data and override only what changes:

const [user, setUser] = useState({ name: '', age: 0 });

// Update only the name, keep the rest
setUser(prevUser => ({ ...prevUser, name: 'Alice' }));
const [items, setItems] = useState([]);

// Add a new item without mutating the original array
setItems(prevItems => [...prevItems, newItem]);

Key Rules and Best Practices

Common Use Cases

Conclusion

useState is the foundational Hook for managing local state in React function components. By understanding how to read and update state, work immutably with objects and arrays, and use the functional updater form, you can build interactive, responsive components with clean and predictable behavior.