diff --git a/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts b/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts index 352d31b2f89..c7c8d6a161e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts @@ -1067,7 +1067,15 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule { name: 'memo-dependencies', description: 'Validates that useMemo() and useCallback() specify comprehensive dependencies without extraneous values. See [`useMemo()` docs](https://react.dev/reference/react/useMemo) for more information.', - preset: LintRulePreset.RecommendedLatest, + /** + * TODO: the "MemoDependencies" rule largely reimplements the "exhaustive-deps" non-compiler rule, + * allowing the compiler to ensure it does not regress change behavior due to different dependencies. + * We previously relied on the source having ESLint suppressions for any exhaustive-deps violations, + * but it's more reliable to verify it within the compiler. + * + * Long-term we should de-duplicate these implementations. + */ + preset: LintRulePreset.Off, }; } case ErrorCategory.IncompatibleLibrary: { diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts index 3d97d4ddf04..1b76dfb43e1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts @@ -303,9 +303,11 @@ function runWithEnvironment( inferReactivePlaces(hir); log({kind: 'hir', name: 'InferReactivePlaces', value: hir}); - if (env.config.validateExhaustiveMemoizationDependencies) { - // NOTE: this relies on reactivity inference running first - validateExhaustiveDependencies(hir).unwrap(); + if (env.enableValidations) { + if (env.config.validateExhaustiveMemoizationDependencies) { + // NOTE: this relies on reactivity inference running first + validateExhaustiveDependencies(hir).unwrap(); + } } rewriteInstructionKindsBasedOnReassignment(hir); diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts index d5f9ab29323..b3a68fc0134 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts @@ -284,7 +284,7 @@ export function validateExhaustiveDependencies( if (missing.length !== 0) { const diagnostic = CompilerDiagnostic.create({ category: ErrorCategory.MemoDependencies, - reason: 'Found non-exhaustive dependencies', + reason: 'Found missing memoization dependencies', description: 'Missing dependencies can cause a value not to update when those inputs change, ' + 'resulting in stale UI', @@ -309,7 +309,7 @@ export function validateExhaustiveDependencies( reason: 'Found unnecessary memoization dependencies', description: 'Unnecessary dependencies can cause a value to update more often than necessary, ' + - 'which can cause effects to run more than expected', + 'causing performance regressions and effects to fire more often than expected', }); diagnostic.withDetails({ kind: 'error', diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.expect.md index bca95a84e1e..ed317be118e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.expect.md @@ -53,7 +53,7 @@ function Component({x, y, z}) { ``` Found 4 errors: -Error: Found non-exhaustive dependencies +Error: Found missing memoization dependencies Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI. @@ -66,7 +66,7 @@ error.invalid-exhaustive-deps.ts:7:11 9 | }, [x?.y.z?.a.b]); 10 | const b = useMemo(() => { -Error: Found non-exhaustive dependencies +Error: Found missing memoization dependencies Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI. @@ -81,7 +81,7 @@ error.invalid-exhaustive-deps.ts:15:11 Error: Found unnecessary memoization dependencies -Unnecessary dependencies can cause a value to update more often than necessary, which can cause effects to run more than expected. +Unnecessary dependencies can cause a value to update more often than necessary, causing performance regressions and effects to fire more often than expected. error.invalid-exhaustive-deps.ts:31:5 29 | return []; @@ -92,7 +92,7 @@ error.invalid-exhaustive-deps.ts:31:5 33 | const ref2 = useRef(null); 34 | const ref = z ? ref1 : ref2; -Error: Found non-exhaustive dependencies +Error: Found missing memoization dependencies Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI.