@samitouri / QOS-React / commits / 67e24bc527

Improve lint error messages for useEffectEvent (#34669)

Called Before: > `logEvent` is a function created with React Hook "useEffectEvent", and can only be called from the same component. Called After: > `logEvent` is a function created with React Hook "useEffectEvent", and can only be called from Effects and Effect Events in the same component. Referenced Before: > `logEvent` is a function created with React Hook "useEffectEvent", and can only be called from the same component. They cannot be assigned to variables or passed down. Referenced After: > `logEvent` is a function created with React Hook "useEffectEvent", and can only be called from Effects and Effect Events in the same component. It cannot be assigned to a variable or passed down.

Jack Pope committed Oct 1, 2025 at 15:17 UTC 67e24bc5279204108b749fe48b4d395ef9e49e67
2 files changed +33 -11
packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js
+19 -3
@@ -1637,17 +1637,32 @@ const allTests = {
1637 const onClick = useEffectEvent(() => {
1638 showNotification(theme);
1639 });
1640 + // error message 1
1641 const onClick2 = () => { onClick() };
1642 + // error message 2
1643 const onClick3 = useCallback(() => onClick(), []);
1644 + // error message 3
1645 + const onClick4 = onClick;
1646 return <>
1647 + {/** error message 4 */}
1648 + <Child onClick={onClick}></Child>
1649 <Child onClick={onClick2}></Child>
1650 <Child onClick={onClick3}></Child>
1651 </>;
1652 }
1653 `,
1654 + // Explicitly test error messages here for various cases
1655 errors: [
1649 - useEffectEventError('onClick', true),
1650 - useEffectEventError('onClick', true),
1656 + `\`onClick\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
1657 + 'Effects and Effect Events in the same component.',
1658 + `\`onClick\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
1659 + 'Effects and Effect Events in the same component.',
1660 + `\`onClick\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
1661 + `Effects and Effect Events in the same component. ` +
1662 + `It cannot be assigned to a variable or passed down.`,
1663 + `\`onClick\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
1664 + `Effects and Effect Events in the same component. ` +
1665 + `It cannot be assigned to a variable or passed down.`,
1666 ],
1667 },
1668 ],
@@ -1714,7 +1729,8 @@ function useEffectEventError(fn, called) {
1729 return {
1730 message:
1731 `\`${fn}\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
1717 - `the same component.${called ? '' : ' They cannot be assigned to variables or passed down.'}`,
1732 + 'Effects and Effect Events in the same component.' +
1733 + (called ? '' : ' It cannot be assigned to a variable or passed down.'),
1734 };
1735 }
1736
packages/eslint-plugin-react-hooks/src/rules/RulesOfHooks.ts
+14 -8
@@ -166,10 +166,19 @@ function isEffectIdentifier(node: Node, additionalHooks?: RegExp): boolean {
166
167 return false;
168 }
169 +
170 function isUseEffectEventIdentifier(node: Node): boolean {
171 return node.type === 'Identifier' && node.name === 'useEffectEvent';
172 }
173
174 +function useEffectEventError(fn: string, called: boolean): string {
175 + return (
176 + `\`${fn}\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
177 + 'Effects and Effect Events in the same component.' +
178 + (called ? '' : ' It cannot be assigned to a variable or passed down.')
179 + );
180 +}
181 +
182 function isUseIdentifier(node: Node): boolean {
183 return isReactFunction(node, 'use');
184 }
@@ -769,14 +778,11 @@ const rule = {
778 // This identifier resolves to a useEffectEvent function, but isn't being referenced in an
779 // effect or another event function. It isn't being called either.
780 if (lastEffect == null && useEffectEventFunctions.has(node)) {
772 - const message =
773 - `\`${getSourceCode().getText(
774 - node,
775 - )}\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
776 - 'the same component.' +
777 - (node.parent.type === 'CallExpression'
778 - ? ''
779 - : ' They cannot be assigned to variables or passed down.');
781 + const message = useEffectEventError(
782 + getSourceCode().getText(node),
783 + node.parent.type === 'CallExpression',
784 + );
785 +
786 context.report({
787 node,
788 message,