How to use state in React

Using state is fundamental for creating interactive React components that can store and update data over time, triggering re-renders when values change. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented state management in countless React components for form controls, toggles, modals, and complex interactive elements across enterprise applications. From my expertise, the most effective approach is to use the useState hook with proper state initialization. This method provides simple state management, clear update patterns, and excellent performance while maintaining component isolation and predictable behavior.

Use the useState hook to manage component state with proper initialization and state update functions.

import { useState } from 'react'

function Counter() {
  // State variable with initial value
  const [count, setCount] = useState(0)
  const [message, setMessage] = useState('')

  const increment = () => {
    setCount(count + 1)
  }

  const decrement = () => {
    setCount(prevCount => prevCount - 1)
  }

  const reset = () => {
    setCount(0)
    setMessage('Counter reset!')
  }

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
      <button onClick={reset}>Reset</button>
      {message && <p>{message}</p>}
    </div>
  )
}

// Complex state with objects
function UserForm() {
  const [user, setUser] = useState({
    name: '',
    email: '',
    age: ''
  })

  const handleInputChange = (field, value) => {
    setUser(prevUser => ({
      ...prevUser,
      [field]: value
    }))
  }

  return (
    <form>
      <input
        type="text"
        placeholder="Name"
        value={user.name}
        onChange={(e) => handleInputChange('name', e.target.value)}
      />
      <input
        type="email"
        placeholder="Email"
        value={user.email}
        onChange={(e) => handleInputChange('email', e.target.value)}
      />
      <input
        type="number"
        placeholder="Age"
        value={user.age}
        onChange={(e) => handleInputChange('age', e.target.value)}
      />
      <p>User: {JSON.stringify(user, null, 2)}</p>
    </form>
  )
}

The useState hook returns an array with the current state value and a setter function. Initialize state by passing the initial value to useState. Update state by calling the setter function with the new value or a function that receives the previous state. When updating objects or arrays, always create new references using spread operator to ensure React detects changes. Use functional updates when the new state depends on the previous state to avoid stale closures.

Best Practice Note:

This is the same approach we use in CoreUI React components for managing component state and user interactions. Initialize state with appropriate default values, use functional updates for state that depends on previous values, keep state as simple as possible, and consider splitting complex state into multiple useState calls for better organization.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to set focus on an input field after rendering in React
How to set focus on an input field after rendering in React

How to Add a Tab in HTML
How to Add a Tab in HTML

How to show or hide elements in React? A Step-by-Step Guide.
How to show or hide elements in React? A Step-by-Step Guide.

How to concatenate a strings in JavaScript?
How to concatenate a strings in JavaScript?

Answers by CoreUI Core Team