diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateHooksUsage.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateHooksUsage.ts index af59615525..d2c5833f1a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateHooksUsage.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateHooksUsage.ts @@ -7,8 +7,8 @@ import * as t from '@babel/types'; import { + CompilerDiagnostic, CompilerError, - CompilerErrorDetail, ErrorCategory, ErrorSeverity, } from '../CompilerError'; @@ -95,16 +95,16 @@ export function validateHooksUsage( const unconditionalBlocks = computeUnconditionalBlocks(fn); const errors = new CompilerError(); - const errorsByPlace = new Map(); + const errorsByPlace = new Map(); function recordError( loc: SourceLocation, - errorDetail: CompilerErrorDetail, + diagnostic: CompilerDiagnostic, ): void { if (typeof loc === 'symbol') { - errors.pushErrorDetail(errorDetail); + errors.pushDiagnostic(diagnostic); } else { - errorsByPlace.set(loc, errorDetail); + errorsByPlace.set(loc, diagnostic); } } @@ -112,7 +112,7 @@ export function validateHooksUsage( // Once a particular hook has a conditional call error, don't report any further issues for this hook setKind(place, Kind.Error); - const reason = + const description = 'Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)'; const previousError = typeof place.loc !== 'symbol' ? errorsByPlace.get(place.loc) : undefined; @@ -121,16 +121,19 @@ export function validateHooksUsage( * In some circumstances such as optional calls, we may first encounter a "hook may not be referenced as normal values" error. * If that same place is also used as a conditional call, upgrade the error to a conditonal hook error */ - if (previousError === undefined || previousError.reason !== reason) { + if (previousError === undefined || previousError.reason !== description) { recordError( place.loc, - new CompilerErrorDetail({ + CompilerDiagnostic.create({ category: ErrorCategory.Hooks, - description: null, - reason, - loc: place.loc, severity: ErrorSeverity.InvalidReact, + reason: 'Cannot call hooks conditionally', + description, suggestions: null, + }).withDetail({ + kind: 'error', + loc: place.loc, + message: 'Cannot call hook conditionally', }), ); } @@ -141,14 +144,17 @@ export function validateHooksUsage( if (previousError === undefined) { recordError( place.loc, - new CompilerErrorDetail({ + CompilerDiagnostic.create({ category: ErrorCategory.Hooks, - description: null, - reason: - 'Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values', - loc: place.loc, severity: ErrorSeverity.InvalidReact, + reason: 'Cannot reference hooks as regular values', + description: + 'Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values', suggestions: null, + }).withDetail({ + kind: 'error', + loc: place.loc, + message: 'Hooks may not be referenced as values', }), ); } @@ -159,14 +165,17 @@ export function validateHooksUsage( if (previousError === undefined) { recordError( place.loc, - new CompilerErrorDetail({ + CompilerDiagnostic.create({ category: ErrorCategory.Hooks, - description: null, - reason: - 'Hooks must be the same function on every render, but this value may change over time to a different function. See https://react.dev/reference/rules/react-calls-components-and-hooks#dont-dynamically-use-hooks', - loc: place.loc, severity: ErrorSeverity.InvalidReact, + reason: 'Hooks must be the same on every render', + description: + 'Hooks must be the same function on every render, but this value may change over time to a different function. See https://react.dev/reference/rules/react-calls-components-and-hooks#dont-dynamically-use-hooks', suggestions: null, + }).withDetail({ + kind: 'error', + loc: place.loc, + message: 'This value may change to a different function', }), ); } @@ -427,8 +436,8 @@ export function validateHooksUsage( } } - for (const [, error] of errorsByPlace) { - errors.pushErrorDetail(error); + for (const [, diagnostic] of errorsByPlace) { + errors.pushDiagnostic(diagnostic); } return errors.asResult(); } @@ -450,15 +459,18 @@ function visitFunctionExpression(errors: CompilerError, fn: HIRFunction): void { : instr.value.property; const hookKind = getHookKind(fn.env, callee.identifier); if (hookKind != null) { - errors.pushErrorDetail( - new CompilerErrorDetail({ + errors.pushDiagnostic( + CompilerDiagnostic.create({ category: ErrorCategory.Hooks, severity: ErrorSeverity.InvalidReact, - reason: + reason: 'Cannot call hooks within function expressions', + description: 'Hooks must be called at the top level in the body of a function component or custom hook, and may not be called within function expressions. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)', - loc: callee.loc, - description: `Cannot call ${hookKind === 'Custom' ? 'hook' : hookKind} within a function expression`, suggestions: null, + }).withDetail({ + kind: 'error', + loc: callee.loc, + message: `Cannot call ${hookKind === 'Custom' ? 'hook' : hookKind} within a function expression`, }), ); } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.conditional-hook-unknown-hook-react-namespace.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.conditional-hook-unknown-hook-react-namespace.expect.md index fbf5ca665b..6ad5a99509 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.conditional-hook-unknown-hook-react-namespace.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.conditional-hook-unknown-hook-react-namespace.expect.md @@ -18,13 +18,15 @@ function Component(props) { ``` Found 1 error: -Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks conditionally + +Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) error.conditional-hook-unknown-hook-react-namespace.ts:4:8 2 | let x = null; 3 | if (props.cond) { > 4 | x = React.useNonexistentHook(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^^^^^^^^^^^^^^^^^ Cannot call hook conditionally 5 | } 6 | return x; 7 | } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.conditional-hooks-as-method-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.conditional-hooks-as-method-call.expect.md index 2f8806787d..d67d048608 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.conditional-hooks-as-method-call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.conditional-hooks-as-method-call.expect.md @@ -18,13 +18,15 @@ function Component(props) { ``` Found 1 error: -Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks conditionally + +Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) error.conditional-hooks-as-method-call.ts:4:8 2 | let x = null; 3 | if (props.cond) { > 4 | x = Foo.useFoo(); - | ^^^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^^^ Cannot call hook conditionally 5 | } 6 | return x; 7 | } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.hook-property-load-local-hook.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.hook-property-load-local-hook.expect.md index 3f8e6403af..57c2bbb226 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.hook-property-load-local-hook.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.hook-property-load-local-hook.expect.md @@ -25,24 +25,28 @@ export const FIXTURE_ENTRYPOINT = { ``` Found 2 errors: -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.hook-property-load-local-hook.ts:7:12 5 | 6 | function Foo() { > 7 | let bar = useFoo.useBar; - | ^^^^^^^^^^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^^^^^^^^^^^^^ Hooks may not be referenced as values 8 | return bar(); 9 | } 10 | -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.hook-property-load-local-hook.ts:8:9 6 | function Foo() { 7 | let bar = useFoo.useBar; > 8 | return bar(); - | ^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^^^ Hooks may not be referenced as values 9 | } 10 | 11 | export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-assign-hook-to-local.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-assign-hook-to-local.expect.md index e07aa2e32c..c4548dbe20 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-assign-hook-to-local.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-assign-hook-to-local.expect.md @@ -16,12 +16,14 @@ function Component(props) { ``` Found 1 error: -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.invalid-assign-hook-to-local.ts:2:12 1 | function Component(props) { > 2 | const x = useState; - | ^^^^^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^^^^^^^^ Hooks may not be referenced as values 3 | const state = x(null); 4 | return state[0]; 5 | } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-aliased-hook-import.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-aliased-hook-import.expect.md index a89b7dc0f0..2ba19ecb78 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-aliased-hook-import.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-aliased-hook-import.expect.md @@ -20,13 +20,15 @@ function Component(props) { ``` Found 1 error: -Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks conditionally + +Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) error.invalid-conditional-call-aliased-hook-import.ts:6:11 4 | let data; 5 | if (props.cond) { > 6 | data = readFragment(); - | ^^^^^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^^^^^ Cannot call hook conditionally 7 | } 8 | return data; 9 | } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-aliased-react-hook.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-aliased-react-hook.expect.md index b5c2a7eb59..35138867a5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-aliased-react-hook.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-aliased-react-hook.expect.md @@ -20,13 +20,15 @@ function Component(props) { ``` Found 1 error: -Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks conditionally + +Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) error.invalid-conditional-call-aliased-react-hook.ts:6:10 4 | let s; 5 | if (props.cond) { > 6 | [s] = state(); - | ^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^ Cannot call hook conditionally 7 | } 8 | return s; 9 | } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-non-hook-imported-as-hook.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-non-hook-imported-as-hook.expect.md index c904e866ff..854cd6b044 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-non-hook-imported-as-hook.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-conditional-call-non-hook-imported-as-hook.expect.md @@ -20,13 +20,15 @@ function Component(props) { ``` Found 1 error: -Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks conditionally + +Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) error.invalid-conditional-call-non-hook-imported-as-hook.ts:6:11 4 | let data; 5 | if (props.cond) { > 6 | data = useArray(); - | ^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^ Cannot call hook conditionally 7 | } 8 | return data; 9 | } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-pass-hook-as-call-arg.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-pass-hook-as-call-arg.expect.md index 125faae800..c29dbf849d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-pass-hook-as-call-arg.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-pass-hook-as-call-arg.expect.md @@ -14,12 +14,14 @@ function Component(props) { ``` Found 1 error: -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.invalid-pass-hook-as-call-arg.ts:2:13 1 | function Component(props) { > 2 | return foo(useFoo); - | ^^^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^^^^^^ Hooks may not be referenced as values 3 | } 4 | ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-pass-hook-as-prop.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-pass-hook-as-prop.expect.md index 64914ebbd1..3fa1274416 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-pass-hook-as-prop.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-pass-hook-as-prop.expect.md @@ -14,12 +14,14 @@ function Component(props) { ``` Found 1 error: -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.invalid-pass-hook-as-prop.ts:2:21 1 | function Component(props) { > 2 | return ; - | ^^^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^^^^^^ Hooks may not be referenced as values 3 | } 4 | ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-ternary-with-hook-values.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-ternary-with-hook-values.expect.md index 1f3682bb90..83b1144b34 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-ternary-with-hook-values.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-ternary-with-hook-values.expect.md @@ -15,43 +15,51 @@ function Component(props) { ``` Found 4 errors: -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.invalid-ternary-with-hook-values.ts:2:25 1 | function Component(props) { > 2 | const x = props.cond ? useA : useB; - | ^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^^^^ Hooks may not be referenced as values 3 | return x(); 4 | } 5 | -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.invalid-ternary-with-hook-values.ts:2:32 1 | function Component(props) { > 2 | const x = props.cond ? useA : useB; - | ^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^^^^ Hooks may not be referenced as values 3 | return x(); 4 | } 5 | -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.invalid-ternary-with-hook-values.ts:2:12 1 | function Component(props) { > 2 | const x = props.cond ? useA : useB; - | ^^^^^^^^^^^^^^^^^^^^^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^^^^^^^^^^^^^^^^^^^^^^^^ Hooks may not be referenced as values 3 | return x(); 4 | } 5 | -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.invalid-ternary-with-hook-values.ts:3:9 1 | function Component(props) { 2 | const x = props.cond ? useA : useB; > 3 | return x(); - | ^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^ Hooks may not be referenced as values 4 | } 5 | ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.propertyload-hook.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.propertyload-hook.expect.md index c0998cb6cc..a16b3e52be 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.propertyload-hook.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.propertyload-hook.expect.md @@ -15,23 +15,27 @@ function Component() { ``` Found 2 errors: -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.propertyload-hook.ts:2:12 1 | function Component() { > 2 | const x = Foo.useFoo; - | ^^^^^^^^^^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^^^^^^^^^^ Hooks may not be referenced as values 3 | return x(); 4 | } 5 | -Error: Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values +Error: Cannot reference hooks as regular values + +Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values error.propertyload-hook.ts:3:9 1 | function Component() { 2 | const x = Foo.useFoo; > 3 | return x(); - | ^ Hooks may not be referenced as normal values, they must be called. See https://react.dev/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values + | ^ Hooks may not be referenced as values 4 | } 5 | ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/error.bail.rules-of-hooks-3d692676194b.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/error.bail.rules-of-hooks-3d692676194b.expect.md index 7371cda580..3dba017e22 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/error.bail.rules-of-hooks-3d692676194b.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/error.bail.rules-of-hooks-3d692676194b.expect.md @@ -22,15 +22,15 @@ const ComponentWithHookInsideCallback = React.forwardRef((props, ref) => { ``` Found 1 error: -Error: Hooks must be called at the top level in the body of a function component or custom hook, and may not be called within function expressions. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks within function expressions -Cannot call hook within a function expression. +Hooks must be called at the top level in the body of a function component or custom hook, and may not be called within function expressions. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) error.bail.rules-of-hooks-3d692676194b.ts:8:4 6 | const ComponentWithHookInsideCallback = React.forwardRef((props, ref) => { 7 | useEffect(() => { > 8 | useHookInsideCallback(); - | ^^^^^^^^^^^^^^^^^^^^^ Hooks must be called at the top level in the body of a function component or custom hook, and may not be called within function expressions. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^^^^^^^^^^^^^^ Cannot call hook within a function expression 9 | }); 10 | return ; 11 | }); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-8566f9a360e2.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-8566f9a360e2.expect.md index 520a8e4097..004593f168 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-8566f9a360e2.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-8566f9a360e2.expect.md @@ -22,13 +22,15 @@ const MemoizedButton = memo(function (props) { ``` Found 1 error: -Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks conditionally + +Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) todo.error.invalid-rules-of-hooks-8566f9a360e2.ts:8:4 6 | const MemoizedButton = memo(function (props) { 7 | if (props.fancy) { > 8 | useCustomHook(); - | ^^^^^^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^^^^^^ Cannot call hook conditionally 9 | } 10 | return ; 11 | }); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-a0058f0b446d.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-a0058f0b446d.expect.md index acd4ff9395..ac00fbb99b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-a0058f0b446d.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-a0058f0b446d.expect.md @@ -21,13 +21,15 @@ function ComponentWithConditionalHook() { ``` Found 1 error: -Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks conditionally + +Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) todo.error.invalid-rules-of-hooks-a0058f0b446d.ts:8:4 6 | function ComponentWithConditionalHook() { 7 | if (cond) { > 8 | Namespace.useConditionalHook(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Cannot call hook conditionally 9 | } 10 | } 11 | diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-27c18dc8dad2.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-27c18dc8dad2.expect.md index 8f2783f969..dc4424c1d9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-27c18dc8dad2.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-27c18dc8dad2.expect.md @@ -22,13 +22,15 @@ const FancyButton = React.forwardRef((props, ref) => { ``` Found 1 error: -Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks conditionally + +Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) todo.error.rules-of-hooks-27c18dc8dad2.ts:8:4 6 | const FancyButton = React.forwardRef((props, ref) => { 7 | if (props.fancy) { > 8 | useCustomHook(); - | ^^^^^^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^^^^^^ Cannot call hook conditionally 9 | } 10 | return ; 11 | }); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-d0935abedc42.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-d0935abedc42.expect.md index 343c51787e..f0e0797a84 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-d0935abedc42.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-d0935abedc42.expect.md @@ -21,13 +21,15 @@ React.unknownFunction((foo, bar) => { ``` Found 1 error: -Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks conditionally + +Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) todo.error.rules-of-hooks-d0935abedc42.ts:8:4 6 | React.unknownFunction((foo, bar) => { 7 | if (foo) { > 8 | useNotAHook(bar); - | ^^^^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^^^^ Cannot call hook conditionally 9 | } 10 | }); 11 | diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-e29c874aa913.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-e29c874aa913.expect.md index a9960ad44d..44252e995d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-e29c874aa913.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-e29c874aa913.expect.md @@ -22,13 +22,15 @@ function useHook() { ``` Found 1 error: -Error: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks conditionally + +Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) todo.error.rules-of-hooks-e29c874aa913.ts:9:4 7 | try { 8 | f(); > 9 | useState(); - | ^^^^^^^^ Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^ Cannot call hook conditionally 10 | } catch {} 11 | } 12 | diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/error.invalid-nested-use-effect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/error.invalid-nested-use-effect.expect.md index 2e767c3c71..9a8dc80109 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/error.invalid-nested-use-effect.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/error.invalid-nested-use-effect.expect.md @@ -30,15 +30,15 @@ function Component(props) { ``` Found 1 error: -Error: Hooks must be called at the top level in the body of a function component or custom hook, and may not be called within function expressions. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) +Error: Cannot call hooks within function expressions -Cannot call useEffect within a function expression. +Hooks must be called at the top level in the body of a function component or custom hook, and may not be called within function expressions. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) error.invalid-nested-use-effect.ts:9:4 7 | }; 8 | useEffect(() => { > 9 | useEffect(() => { - | ^^^^^^^^^ Hooks must be called at the top level in the body of a function component or custom hook, and may not be called within function expressions. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) + | ^^^^^^^^^ Cannot call useEffect within a function expression 10 | function nested() { 11 | fire(foo(props)); 12 | } diff --git a/compiler/packages/eslint-plugin-react-compiler/__tests__/PluginTest-test.ts b/compiler/packages/eslint-plugin-react-compiler/__tests__/PluginTest-test.ts index 6efd069aaf..c7640286f4 100644 --- a/compiler/packages/eslint-plugin-react-compiler/__tests__/PluginTest-test.ts +++ b/compiler/packages/eslint-plugin-react-compiler/__tests__/PluginTest-test.ts @@ -68,9 +68,7 @@ testRule('plugin-recommended', TestRecommendedRules, { ; } `, - errors: [ - makeTestCaseError('Hooks must always be called in a consistent order'), - ], + errors: [makeTestCaseError('Cannot call hooks conditionally')], }, { name: 'Multiple diagnostics within the same file are surfaced', @@ -84,8 +82,8 @@ testRule('plugin-recommended', TestRecommendedRules, { return props.cond && useConditionalHook(); }`, errors: [ - makeTestCaseError('Hooks must always be called in a consistent order'), - makeTestCaseError('Hooks must always be called in a consistent order'), + makeTestCaseError('Cannot call hooks conditionally'), + makeTestCaseError('Cannot call hooks conditionally'), ], }, { @@ -98,9 +96,7 @@ testRule('plugin-recommended', TestRecommendedRules, { } `, - errors: [ - makeTestCaseError('Hooks must always be called in a consistent order'), - ], + errors: [makeTestCaseError('Cannot call hooks conditionally')], }, { name: 'Multiple non-fatal useMemo diagnostics are surfaced',