Skip to content

React Tutorial State and Events

Derived State: Calculate It, Do Not Store It

Lesson 56 of 156 2 min read By Deepak Paswan Updated Oct 10, 2026

Runnable lesson · press Try it on the examples to edit and run them here.

Derived state is a value you can work out from other state or props. The most important rule about it is a short one: do not store it. Calculate it while rendering.

The problem with duplicated state

Here is a shopping list that keeps a separate count in state:

App.jsx
JSX
function App() {
  const [items, setItems] = React.useState(["Milk", "Eggs"]);
  const [count, setCount] = React.useState(2); // duplicated information

  return (
    <div>
      <p>Items: {items.length} (count says {count})</p>
      <button onClick={() => setItems([...items, "Bread"])}>Add item</button>
      {/* We forgot to call setCount. Now the two disagree. */}
    </div>
  );
}

After clicking, the list has three items, but count still says 2. Two sources of truth will drift apart the moment you forget to update one of them. Every extra piece of state is something you must keep in sync.

The fix: derive it

App.jsx
JSX
function App() {
  const [items, setItems] = React.useState(["Milk", "Eggs"]);
  const count = items.length; // calculated on each render, always correct

  return (
    <div>
      <p>Items: {count}</p>
      <button onClick={() => setItems([...items, "Bread"])}>Add item</button>
    </div>
  );
}

Now there is one source of truth. The component re-renders whenever items changes, and count is recalculated from the new value for free.

Common derived values

Most of these should never be state:

  • Counts, totals, averages: items.reduce((sum, i) => sum + i.price, 0)
  • Filtered or sorted lists: see Filtering and Sorting Lists
  • Whether a form is valid: name.length > 0 && email.includes("@")
  • A full name from first and last, built with a template literal such as ${first} ${last}
  • A label from a boolean: open ? "Close" : "Open"
App.jsx
JSX
function App() {
  const catalog = { Pen: 2.5, Book: 15 };
  const [cart, setCart] = React.useState([]);

  const total = cart.reduce((sum, name) => sum + catalog[name], 0);
  const itemWord = cart.length === 1 ? "item" : "items";

  return (
    <div>
      {Object.keys(catalog).map((name) => (
        <button key={name} onClick={() => setCart([...cart, name])}>Add {name}</button>
      ))}
      <p>Total: ${total.toFixed(2)}</p>
      <p>{cart.length} {itemWord}</p>
    </div>
  );
}

The prop-mirroring trap

Copying a prop into state looks harmless, but it freezes the value:

App.jsx
JSX
function Price({ amount }) {
  const [price, setPrice] = useState(amount); // WRONG: ignores later changes to amount
  return <p>{price}</p>;
}

The first value is used, and later changes to amount are ignored. Use the prop directly. If you need an editable copy that starts from the prop, name it initialAmount so everyone knows it is only the starting value, as in Props Are Read-Only.

Expensive calculations

If a derived value takes a long time to compute and its inputs rarely change, you can remember the result with useMemo; see useMemo. Do it only after you have measured a real slowdown. Calculating in render is cheap for most data.

Resetting state when something changes

Sometimes you want state to restart when a prop changes (for example, an edit form when the selected user changes). Do not copy props into state and sync with an effect. Give the component a key, so React makes a new one:

App.jsx
JSX
<EditForm key={user.id} user={user} />

A test question

For any piece of state ask: “Can I calculate this from other state or props?” If yes, it should not be state.

Key points

  • Derived values are calculated during rendering, not stored in state.
  • Duplicate state goes out of sync; one source of truth cannot.
  • Do not copy props into state; use the prop, or reset with key.