Ban direct `useEffect` in React components. Use when writing, refactoring, or reviewing React code so derived state, data fetching, user actions, resets, and mount-only external synchronization use declarative replacement patterns instead of dependency-array choreography.
95
95%
Does it follow best practices?
Impact
98%
1.02xAverage score across 4 eval scenarios
Passed
No known issues
A form component uses one effect to notice a shouldSubmit flag after a button click and another effect to reset local draft state when the selected user changes. Refactor it without direct useEffect.
Keep user-caused work in the event handler. Use a keyed boundary or render-time derivation for reset semantics. Do not rewrite unrelated form behavior.
Produce:
src/UserEditor.tsx with the refactored codeeffect-replacement-report.md summarizing the replacement choices=============== FILE: src/UserEditor.tsx =============== import { useEffect, useState } from "react";
type User = { id: string; name: string };
async function saveUser(userId: string, name: string) {
await fetch(/api/users/${userId}, {
method: "POST",
body: JSON.stringify({ name }),
});
}
export function UserEditor({ user }: { user: User }) { const [name, setName] = useState(user.name); const [shouldSubmit, setShouldSubmit] = useState(false);
useEffect(() => { setName(user.name); }, [user.id, user.name]);
useEffect(() => { if (!shouldSubmit) return; setShouldSubmit(false); void saveUser(user.id, name); }, [shouldSubmit, user.id, name]);
return (
<input value={name} onChange={(event) => setName(event.target.value)} /> <button type="button" onClick={() => setShouldSubmit(true)}> Save ); } =============== END FILE ===============