From c741d2db648d57dce07dc14c0b00a1944696e790 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Wed, 28 Aug 2024 16:54:04 -0700 Subject: [PATCH] [compiler] Silence ref-in-render errors in ESLint We need this for compiler correctness but the false positive rate is a bit too high, let's suppress in ESLint for now. ghstack-source-id: 2d24397b1b8e68043946cf38ef5fe9b041575277 Pull Request resolved: https://github.com/facebook/react/pull/30843 --- .../src/CompilerError.ts | 6 ++++ .../Validation/ValidateNoRefAccesInRender.ts | 8 ++--- ...r.capture-ref-for-later-mutation.expect.md | 8 ++--- ...invalid-access-ref-during-render.expect.md | 2 +- ...-callback-invoked-during-render-.expect.md | 2 +- ...-disallow-mutating-ref-in-render.expect.md | 2 +- ...tating-refs-in-render-transitive.expect.md | 4 +-- ...ror.invalid-pass-ref-to-function.expect.md | 2 +- ...d-ref-prop-in-render-destructure.expect.md | 2 +- ...ref-prop-in-render-property-load.expect.md | 2 +- ...n-callback-invoked-during-render.expect.md | 2 +- ...error.invalid-ref-value-as-props.expect.md | 2 +- ...d-set-and-read-ref-during-render.expect.md | 4 +-- ...ef-nested-property-during-render.expect.md | 4 +-- ...f-added-to-dep-without-type-info.expect.md | 4 +-- ...rite-but-dont-read-ref-in-render.expect.md | 2 +- ...invalid-write-ref-prop-in-render.expect.md | 2 +- .../error.repro-ref-mutable-range.expect.md | 2 +- ...ified-later-preserve-memoization.expect.md | 2 +- ...ia-function-preserve-memoization.expect.md | 4 +-- ...operty-dont-preserve-memoization.expect.md | 2 +- ...alidate-mutate-ref-arg-in-render.expect.md | 2 +- ...r.capture-ref-for-later-mutation.expect.md | 8 ++--- ....maybe-mutable-ref-not-preserved.expect.md | 2 +- .../error.useMemo-with-refs.flow.expect.md | 2 +- .../__tests__/ReactCompilerRule-test.ts | 36 ++++++++++++++++--- 26 files changed, 75 insertions(+), 43 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts b/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts index 5ea6f9862815f..bfdf6b9e9f02d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts @@ -18,6 +18,11 @@ export enum ErrorSeverity { * Code that breaks the rules of React. */ InvalidReact = 'InvalidReact', + /** + * Like InvalidReact, but this specific error is still in testing w some false positives + * so we special-case it to suppress in ESLint. + */ + InvalidRefInRender = 'InvalidRefInRender', /** * Incorrect configuration of the compiler. */ @@ -232,6 +237,7 @@ export class CompilerError extends Error { case ErrorSeverity.InvalidJS: case ErrorSeverity.InvalidReact: case ErrorSeverity.InvalidConfig: + case ErrorSeverity.InvalidRefInRender: return true; case ErrorSeverity.CannotPreserveMemoization: case ErrorSeverity.Todo: diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts index 8a65b4709c174..1732c0a5af614 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts @@ -246,7 +246,7 @@ function validateNoRefAccessInRenderImpl( // Report a more precise error when calling a local function that accesses a ref if (state.refAccessingFunctions.has(callee.identifier.id)) { errors.push({ - severity: ErrorSeverity.InvalidReact, + severity: ErrorSeverity.InvalidRefInRender, reason: 'This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)', loc: callee.loc, @@ -351,7 +351,7 @@ function validateNoRefValueAccess( state.refAccessingFunctions.has(operand.identifier.id) ) { errors.push({ - severity: ErrorSeverity.InvalidReact, + severity: ErrorSeverity.InvalidRefInRender, reason: 'Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)', loc: state.refValues.get(operand.identifier.id) ?? operand.loc, @@ -377,7 +377,7 @@ function validateNoRefAccess( state.refAccessingFunctions.has(operand.identifier.id) ) { errors.push({ - severity: ErrorSeverity.InvalidReact, + severity: ErrorSeverity.InvalidRefInRender, reason: 'Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)', loc: loc, @@ -398,7 +398,7 @@ function validateNoDirectRefValueAccess( ): void { if (state.refValues.has(operand.identifier.id)) { errors.push({ - severity: ErrorSeverity.InvalidReact, + severity: ErrorSeverity.InvalidRefInRender, reason: 'Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)', loc: state.refValues.get(operand.identifier.id) ?? operand.loc, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.capture-ref-for-later-mutation.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.capture-ref-for-later-mutation.expect.md index 52350036257d0..244a26cd01422 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.capture-ref-for-later-mutation.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.capture-ref-for-later-mutation.expect.md @@ -35,13 +35,13 @@ export const FIXTURE_ENTRYPOINT = { 10 | }; 11 | const moveLeft = { > 12 | handler: handleKey('left'), - | ^^^^^^^^^ InvalidReact: This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef) (12:12) + | ^^^^^^^^^ InvalidRefInRender: This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef) (12:12) -InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (12:12) +InvalidRefInRender: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (12:12) -InvalidReact: This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef) (15:15) +InvalidRefInRender: This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef) (15:15) -InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (15:15) +InvalidRefInRender: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (15:15) 13 | }; 14 | const moveRight = { 15 | handler: handleKey('right'), diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md index 02748366456fb..e84e74f7399b8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md @@ -18,7 +18,7 @@ function Component(props) { 2 | function Component(props) { 3 | const ref = useRef(null); > 4 | const value = ref.current; - | ^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (4:4) + | ^^^^^^^^^^^ InvalidRefInRender: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (4:4) 5 | return value; 6 | } 7 | diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-aliased-ref-in-callback-invoked-during-render-.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-aliased-ref-in-callback-invoked-during-render-.expect.md index e2ce2cceae3b9..2485dbfdfdbcc 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-aliased-ref-in-callback-invoked-during-render-.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-aliased-ref-in-callback-invoked-during-render-.expect.md @@ -22,7 +22,7 @@ function Component(props) { 7 | return ; 8 | }; > 9 | return {props.items.map(item => renderItem(item))}; - | ^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (9:9) + | ^^^^^^^^^^^^^^^^^^^^^^^^ InvalidRefInRender: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (9:9) 10 | } 11 | ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-disallow-mutating-ref-in-render.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-disallow-mutating-ref-in-render.expect.md index b5547a1328629..0876bcb8f78bb 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-disallow-mutating-ref-in-render.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-disallow-mutating-ref-in-render.expect.md @@ -19,7 +19,7 @@ function Component() { 2 | function Component() { 3 | const ref = useRef(null); > 4 | ref.current = false; - | ^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (4:4) + | ^^^^^^^^^^^ InvalidRefInRender: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (4:4) 5 | 6 | return