Skip to content

State

beginner2 min read
  • React
  • JavaScript

A component's memory: data that changes over time and, when updated through the setter, causes React to re-render the component with the new value.

Prerequisites

  • Props and one-way data flow (see Related Topics)

What you'll understand

  • What state is and how it differs from props
  • How updating state triggers a re-render
  • Why you must use the setter instead of assigning directly

Explanation

State is a component’s memory: data that belongs to the component and can change over time, such as the current value of an input, whether a menu is open, or a counter. Unlike props, which come from the parent and are read-only, state is owned by the component itself and is meant to change.

You declare state with the useState hook (see Related Topics), which gives you the current value and a setter function. The setter is the important half: calling it does two things at once, it updates the stored value and tells React to re-render the component so the screen reflects the new value. This is how a React UI stays in sync with its data, you change the state, and the interface updates itself.

Because updates go through the setter, you must never change state by assigning to the variable directly; React would not know anything changed and would not re-render. You also treat state as immutable: to update an object or array, you create a new one and pass it to the setter rather than mutating the existing value in place.

Examples

This component holds a count in state and updates it through the setter, which triggers a re-render:

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}

To update an array in state, create a new array rather than mutating it:

setItems([...items, newItem]); // correct: a new array
// items.push(newItem);        // wrong: mutates state directly

Common mistakes

  • Assigning to the state variable directly instead of calling the setter.
  • Mutating an object or array in state instead of creating a new one.
  • Putting data in state that could just be derived from existing props or state.
  • Expecting the state variable to update synchronously right after calling the setter.

Best practices

  • Always update state through its setter function.
  • Treat state as immutable; produce new objects and arrays.
  • Keep the minimal state needed and derive the rest during render.
  • Store in state only what changes over time and affects the UI.

Further reading

Related topics