Linter · Rules
react-hooks/no-deriving-state-in-effects
Disallow effects that only compute state from props or other state
An effect runs after the component has rendered. If all it does is compute a value from props or state and store it with a useState setter, React renders once with the stale value, runs the effect, and renders again. Compute the value while rendering instead. It's always up to date, and the extra state and the extra render go away.
The rule reports an effect if it uses nothing but its dependencies and state setters, and the value it stores is made from all of its dependencies.
Configure
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"react-hooks/no-deriving-state-in-effects" = "error" # or "warn"
Examples
Reported:
import { useEffect, useState } from "react";
function Greeting({ firstName, lastName }) {
const [fullName, setFullName] = useState("");
useEffect(() => {
setFullName(firstName + " " + lastName);
}, [firstName, lastName]);
return <h1>{fullName}</h1>;
}
Not reported:
function Greeting({ firstName, lastName }) {
const fullName = firstName + " " + lastName;
return <h1>{fullName}</h1>;
}
Talking to something outside React is what effects are for:
import { useEffect, useState } from "react";
function Profile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then(setUser);
}, [userId]);
return <h1>{user?.name}</h1>;
}