The issue involves detecting state updates in anonymous components within higher-order functions.
The issue reports that the `react-hooks/set-state-in-effect` rule fails to detect `setState` calls in `useEffect` when the component is an anonymous callback passed to a higher-order function. The fix likely involves updating the rule to handle this case, but requires understanding of React DevTools and AST parsing.
https://codesandbox.io/p/sandbox/github/codesandbox/sandbox-templates/tree/main/nextjs
react-hooks/set-state-in-effect reports setState in a normal component's useEffect, but misses the same pattern when the component is an anonymous callback passed to a higher-order function.
// app/ComponentToCheck.ts
import { useEffect, useState } from 'react'
const wrap = (value) => value
export function DirectComponent() {
const [value, setValue] = useState(0)
useEffect(() => {
// Direct
setValue(1)
}, [])
return <div>{value}</div>
}
export const WrappedAnonymousComponent = wrap(() => {
const [value, setValue] = useState(0)
useEffect(() => {
// in HOC
setValue(1)
}, [])
return <div>{value}</div>
})
Running pnpm eslint app/ComponentToCheck.ts finds only the use of setValue in the useEffect of DirectComponent:
➜ workspace git:(main) ✗ pnpm eslint app/ComponentToCheck.ts
> [email protected] eslint /project/workspace
> eslint "app/ComponentToCheck.ts"
/project/workspace/app/ComponentToCheck.ts
10: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/ComponentToCheck.ts:10:5
8 | useEffect(() => {
9 | // Direct
> 10 | setValue(1)
| ^^^^^^^^ Avoid calling setState() directly
Claim this issue to let others know you're working on it. You'll earn 20 points when you complete it!