Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
290174c38f |
@@ -1067,7 +1067,15 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
|
|||||||
name: 'memo-dependencies',
|
name: 'memo-dependencies',
|
||||||
description:
|
description:
|
||||||
'Validates that useMemo() and useCallback() specify comprehensive dependencies without extraneous values. See [`useMemo()` docs](https://react.dev/reference/react/useMemo) for more information.',
|
'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: {
|
case ErrorCategory.IncompatibleLibrary: {
|
||||||
|
|||||||
@@ -303,9 +303,11 @@ function runWithEnvironment(
|
|||||||
inferReactivePlaces(hir);
|
inferReactivePlaces(hir);
|
||||||
log({kind: 'hir', name: 'InferReactivePlaces', value: hir});
|
log({kind: 'hir', name: 'InferReactivePlaces', value: hir});
|
||||||
|
|
||||||
if (env.config.validateExhaustiveMemoizationDependencies) {
|
if (env.enableValidations) {
|
||||||
// NOTE: this relies on reactivity inference running first
|
if (env.config.validateExhaustiveMemoizationDependencies) {
|
||||||
validateExhaustiveDependencies(hir).unwrap();
|
// NOTE: this relies on reactivity inference running first
|
||||||
|
validateExhaustiveDependencies(hir).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rewriteInstructionKindsBasedOnReassignment(hir);
|
rewriteInstructionKindsBasedOnReassignment(hir);
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ export function validateExhaustiveDependencies(
|
|||||||
if (missing.length !== 0) {
|
if (missing.length !== 0) {
|
||||||
const diagnostic = CompilerDiagnostic.create({
|
const diagnostic = CompilerDiagnostic.create({
|
||||||
category: ErrorCategory.MemoDependencies,
|
category: ErrorCategory.MemoDependencies,
|
||||||
reason: 'Found non-exhaustive dependencies',
|
reason: 'Found missing memoization dependencies',
|
||||||
description:
|
description:
|
||||||
'Missing dependencies can cause a value not to update when those inputs change, ' +
|
'Missing dependencies can cause a value not to update when those inputs change, ' +
|
||||||
'resulting in stale UI',
|
'resulting in stale UI',
|
||||||
@@ -309,7 +309,7 @@ export function validateExhaustiveDependencies(
|
|||||||
reason: 'Found unnecessary memoization dependencies',
|
reason: 'Found unnecessary memoization dependencies',
|
||||||
description:
|
description:
|
||||||
'Unnecessary dependencies can cause a value to update more often than necessary, ' +
|
'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({
|
diagnostic.withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ function Component({x, y, z}) {
|
|||||||
```
|
```
|
||||||
Found 4 errors:
|
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.
|
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]);
|
9 | }, [x?.y.z?.a.b]);
|
||||||
10 | const b = useMemo(() => {
|
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.
|
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
|
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
|
error.invalid-exhaustive-deps.ts:31:5
|
||||||
29 | return [];
|
29 | return [];
|
||||||
@@ -92,7 +92,7 @@ error.invalid-exhaustive-deps.ts:31:5
|
|||||||
33 | const ref2 = useRef(null);
|
33 | const ref2 = useRef(null);
|
||||||
34 | const ref = z ? ref1 : ref2;
|
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.
|
Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user