-
Notifications
You must be signed in to change notification settings - Fork 49.5k
Open
Labels
Status: UnconfirmedA potential issue that we haven't yet confirmed as a bugA potential issue that we haven't yet confirmed as a bug
Description
eslint-plugin-react-hooks version: 6.1.1
Steps To Reproduce
- Use common, valid patterns for setting state in an effect, from those in the wild and official docs (see patterns in section below)
- Problem reported by
eslint-plugin-react-hooks
💥
Link to code example: https://codesandbox.io/p/devbox/still-resonance-lzsl44?file=%2Fapp%2FComponent.tsx%3A10%2C49&workspaceId=ws_GfAuHrswXyA1DoeSwsjjjz

$ pnpm eslint . --max-warnings 0
/project/workspace/app/Component.tsx
7:5 error Error: Calling setState synchronously within an effect can trigger cascading renders
Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:
* Update external systems with the latest state from React.
* Subscribe for updates from some external system, calling setState in a callback function when external state changes.
Calling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect).
/project/workspace/app/Component.tsx:7:5
5 |
6 | useEffect(() => {
> 7 | setDidMount(true);
| ^^^^^^^^^^^ Avoid calling setState() directly within an effect
8 | }, []);
9 |
10 | return <div>Mounted: {didMount ? "Yes" : "No"}</div>; react-hooks/set-state-in-effect
✖ 1 problem (1 error, 0 warnings)
Widespread setState in useEffect
Patterns
- Displaying different content on the server and client aka
didMount
,isClient
,isMounted
,mounted
React docs 1, React docs 2, Next.js docs, next-themes docs, MUI Joy UI docs - Setting a value while avoiding cascading renders from @controversial
[Compiler Bug]: False positives “calling setState synchronously within an effect body” with stable primitive values #34045
I will add any more common patterns I find to the list as I encounter more examples.
The current behavior
react-hooks/set-state-in-effect
raises a problem with the message Calling setState synchronously within an effect can trigger cascading renders
The expected behavior
react-hooks/set-state-in-effect
is less strict, allowing for common usage patterns while catching possible "effect loops" or other unwanted behavior
Alternatives considered
- Improved examples on the
react-hooks/set-state-in-effect
docs page, showing more patterns such as the remediation patterns mentioned below that can be used in lieu of setting state directly in an effect (possible downside: some patterns may not have usable replacements outside of setting state in effects) - Improved examples on the
react-hooks/set-state-in-effect
docs page, showing alternative patterns with setting state directly in an effect eg. usingstartTransition()
,requestAnimationFrame()
orsetTimeout()
(downside: seems wrong, like a code smell or "tricking the lint rule")
History
- The React Compiler team is aware of problems like this and is thinking about how to better handle false positives [Compiler Bug]: False positives “calling setState synchronously within an effect body” with stable primitive values #34045 (comment)
Metadata
Metadata
Assignees
Labels
Status: UnconfirmedA potential issue that we haven't yet confirmed as a bugA potential issue that we haven't yet confirmed as a bug