noctcore-react/no-effect-derived-state
An effect that only sets state derived from its dependencies is the “you might not need an effect” anti-pattern.
Recommended preset: error · Autofix: no · Suggestions: no · Type information: not needed
An effect whose only job is to setState a value purely derived from its own dependencies should
not exist — the value should be computed during render (or with useMemo). The effect version runs
an extra render pass, flashes stale UI for a frame, and is a common source of update loops. See the
React docs, “You Might Not Need an Effect”.
Severity
Section titled “Severity”Ships as error in the recommended preset. It is a heuristic, which is an argument for keeping
it narrow rather than advisory: it fires only on an effect whose whole body is setX(...) of
values read from its own deps, and anything with a branch, a call or a cleanup bails out
unflagged.
What it flags
Section titled “What it flags”This rule is deliberately conservative — it fires only on the unambiguous shape:
- a
useEffect/useLayoutEffectwith a dependency array; - a non-async callback whose body is nothing but
setX(...)statements; - every setter argument is a pure expression (no calls, awaits,
new, JSX, or assignments) whose identifiers all resolve to a dependency; - at least one argument actually reads a dependency.
// derived state synced through an effectuseEffect(() => { setFullName(firstName + ' ' + lastName);}, [firstName, lastName]);// compute during renderconst fullName = firstName + ' ' + lastName;What it does not flag
Section titled “What it does not flag”Anything with a branch, a side effect, an await, a cleanup, or an argument that reaches outside the dependency array bails out unflagged:
- a setter argument that is a call (
setX(compute(a))), which could be impure; - an effect with no dependency array, or an
asynccallback; - a constant initialiser (
setX(0)) that reads no dependency; - an
if, a cleanupreturn, or any statement besides the setters.
When not to use it
Section titled “When not to use it”If you rely on the extra render pass an effect gives you (rare, and usually a smell), disable it.