Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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.

Expand All @@ -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 [];
Expand All @@ -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.

Expand Down
Loading