ESLint rule incorrectly flags valid React code.
The issue involves a false positive from the `react-hooks/set-state-in-effect` ESLint rule, which incorrectly flags valid React code using `useLayoutEffect` with refs. The problem appears to be related to recent updates in `eslint-plugin-react-hooks`. The scope is somewhat clear, but diagnosing the root cause may require deeper knowledge of ESLint rules and React internals.
React version: [email protected], [email protected]
eslint-plugin-react-hooks and the react-hooks/set-state-in-effect rule enabledLink to code example:
https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect#valid
// ✅ setState in an effect is fine if the value comes from a ref
function Tooltip() {
const ref = useRef(null);
const [tooltipHeight, setTooltipHeight] = useState(0);
useLayoutEffect(() => {
const { height } = ref.current.getBoundingClientRect();
setTooltipHeight(height);
}, []);
}
Typescript variant, with usage:
export function Tooltip(): ReactElement {
const ref = useRef<HTMLDivElement>(null);
const [tooltipHeight, setTooltipHeight] = useState(0);
useLayoutEffect(() => {
const height = ref.current?.getBoundingClientRect().height ?? 0;
setTooltipHeight(height);
}, []);
return <div ref={ref}>{tooltipHeight}</div>;
}
Another similar example that also triggered this error:
function Foo(): ReactElement {
const ref = useRef<HTMLDivElement>(null);
const [isWithinBar, setIsWithinBar] = useState(false);
useLayoutEffect(() => {
setIsWithinBar(ref.current?.closest('.bar') != null);
}, []);
return <div ref={ref} className={isWithinBar ? 'variant-1' : 'variant-2'}>Foo</div>
}
The code, straight out of the valid section of the docs, triggers an ESLint error of react-hooks/set-state-in-effect:
Valid usage of useLayoutEffect to do measurements and DOM checks via refs and setting state should not generat
Claim this issue to let others know you're working on it. You'll earn 10 points when you complete it!