Deriving State — Calculate It, Don't Store It
Remove unnecessary state and effects by deriving values from existing state.
Introduction
Deriving state means calculating values from existing state or props instead of storing them separately. In React, this keeps your data model minimal and avoids bugs where multiple pieces of state fall out of sync.
Why this matters
If a value can be computed from existing state or props, don’t store it separately. Duplicate state invites bugs and effect spaghetti when values drift out of sync.
The problem
Storing a derived fullName and syncing it in an effect whenever firstName or lastName changes adds extra state and re-renders you don’t need.
Inefficient approach
Duplicating derived values in state introduces sync bugs and unnecessary effects:
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 solution
Compute fullName inline—no extra state or effects needed.
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;
Step-by-step
-
Remove
fullNamestate and its setter. -
Remove the effect that syncs
fullName. -
Add a local variable:
const fullName = firstName + " " + lastName. -
Render
fullNamedirectly.
Tips
-
If a value is derived, prefer variables or memoization (
useMemo) over state. -
Use state for values that change due to events and aren’t derivable from other inputs.
-
Removing effects often improves correctness and performance.
Knowledge base
Problem snippet:
const [fullName, setFullName] = useState("");
useEffect(() => setFullName(`${firstName} ${lastName}`), [firstName, lastName]);
Solution snippet:
const fullName = `${firstName} ${lastName}`;