Deriving State: Calculate It, Don't Store It
Remove unnecessary state and effects by deriving values from existing state.
I used to store computed values in state and sync them with an effect. fullName is the classic case, and it costs an extra state field, an effect, and re-renders you don’t need.
The Effect-Synced Version
import { useState, useEffect } from "react";
function App() {
const [firstName] = useState("John");
const [lastName] = useState("Doe");
const [fullName, setFullName] = useState("");
useEffect(() => {
setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);
return (
<div>
<h1>Deriving State</h1>
<p>First Name: {firstName}</p>
<p>Last Name: {lastName}</p>
<p>Full Name: {fullName}</p>
</div>
);
}
export default App;
The effect watches firstName and lastName and rewrites fullName after the component has already rendered once. There’s an extra piece of state here, kept in sync by hand, and anything kept in sync by hand can drift.
Just Compute It
fullName is fully determined by values the component already holds. Delete the state, the setter, and the effect, and compute it as a local variable during render.
import { useState } from "react";
function App() {
const [firstName] = useState("John");
const [lastName] = useState("Doe");
const fullName = `${firstName} ${lastName}`;
return (
<div>
<h1>Deriving State</h1>
<p>First Name: {firstName}</p>
<p>Last Name: {lastName}</p>
<p>Full Name: {fullName}</p>
</div>
);
}
export default App;
One source of truth, nothing to sync, no extra render.
Where State Still Belongs
My line is simple. If a value can be computed from state or props, it stays a variable, or goes into useMemo when I need it. State is for values that change because of events and can’t be derived from other inputs. Removing effects like this one tends to improve correctness and performance together.