stackademic

The leading education platform for anyone with an interest in software development.

useState

Add local state to function components and trigger re-renders on updates

Overview

useState is the primary hook for local component state. Calling the setter schedules a re-render with the new value. State updates are asynchronous and may be batched in event handlers.

Syntax / Usage

import { useState } from 'react'

function Counter() {
  const [count, setCount] = useState(0)
  const [user, setUser] = useState({ name: '', email: '' })

  // Functional update when next state depends on previous
  const increment = () => setCount((prev) => prev + 1)

  // Object updates—spread to avoid mutating
  const updateName = (name) =>
    setUser((prev) => ({ ...prev, name }))

  return (
    <button onClick={increment}>
      Count: {count}
    </button>
  )
}

Lazy initialization: useState(() => expensiveComputation()) runs only on first render.

Examples

Controlled text input:

function SearchBox() {
  const [query, setQuery] = useState('')

  return (
    <input
      value={query}
      onChange={(e) => setQuery(e.target.value)}
      placeholder="Search..."
    />
  )
}

Toggle dark mode:

function ThemeToggle() {
  const [dark, setDark] = useState(false)
  return (
    <button onClick={() => setDark((d) => !d)}>
      {dark ? 'Light' : 'Dark'} mode
    </button>
  )
}

Common Mistakes

  • Mutating state objects/arrays directly instead of creating new references
  • Assuming setState updates immediately—read state in useEffect after changes
  • Storing derived values in state when you can compute them during render
  • Too many useState calls—group related fields or use useReducer

See Also

use-effect use-ref props components