react-hooks/no-deriving-state-in-effects

Disallow effects that only compute state from props or other state

Also called react_hooks/no-deriving-state-in-effects, react/no-deriving-state-in-effects

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#

example.jsx1 problem
import { useEffect, useState } from "react";

function Greeting({ firstName, lastName }) {
  const [fullName, setFullName] = useState("");

  useEffect(() => {
    setFullName(firstName + " " + lastName);
  }, [firstName, lastName]);

  return <h1>{fullName}</h1>;
}
example.jsxNo problems
function Greeting({ firstName, lastName }) {
  const fullName = firstName + " " + lastName;

  return <h1>{fullName}</h1>;
}

Talking to something outside React is what effects are for:

example.jsxNo problems
import { useEffect, useState } from "react";

function Profile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetchUser(userId).then(setUser);
  }, [userId]);

  return <h1>{user?.name}</h1>;
}