Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2283eb9183 |
@@ -59,7 +59,7 @@ export type CompilerDiagnosticDetail =
|
||||
*/
|
||||
{
|
||||
kind: 'error';
|
||||
loc: SourceLocation;
|
||||
loc: SourceLocation | null;
|
||||
message: string;
|
||||
};
|
||||
|
||||
@@ -100,6 +100,12 @@ export class CompilerDiagnostic {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
static create(
|
||||
options: Omit<CompilerDiagnosticOptions, 'details'>,
|
||||
): CompilerDiagnostic {
|
||||
return new CompilerDiagnostic({...options, details: []});
|
||||
}
|
||||
|
||||
get category(): CompilerDiagnosticOptions['category'] {
|
||||
return this.options.category;
|
||||
}
|
||||
@@ -113,6 +119,11 @@ export class CompilerDiagnostic {
|
||||
return this.options.suggestions;
|
||||
}
|
||||
|
||||
withDetail(detail: CompilerDiagnosticDetail): CompilerDiagnostic {
|
||||
this.options.details.push(detail);
|
||||
return this;
|
||||
}
|
||||
|
||||
primaryLocation(): SourceLocation | null {
|
||||
return this.options.details.filter(d => d.kind === 'error')[0]?.loc ?? null;
|
||||
}
|
||||
@@ -127,7 +138,7 @@ export class CompilerDiagnostic {
|
||||
switch (detail.kind) {
|
||||
case 'error': {
|
||||
const loc = detail.loc;
|
||||
if (typeof loc === 'symbol') {
|
||||
if (loc == null || typeof loc === 'symbol') {
|
||||
continue;
|
||||
}
|
||||
let codeFrame: string;
|
||||
|
||||
@@ -9,6 +9,7 @@ import {NodePath, Scope} from '@babel/traverse';
|
||||
import * as t from '@babel/types';
|
||||
import invariant from 'invariant';
|
||||
import {
|
||||
CompilerDiagnostic,
|
||||
CompilerError,
|
||||
CompilerSuggestionOperation,
|
||||
ErrorSeverity,
|
||||
@@ -104,12 +105,18 @@ export function lower(
|
||||
if (param.isIdentifier()) {
|
||||
const binding = builder.resolveIdentifier(param);
|
||||
if (binding.kind !== 'Identifier') {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lower) Could not find binding for param \`${param.node.name}\``,
|
||||
severity: ErrorSeverity.Invariant,
|
||||
loc: param.node.loc ?? null,
|
||||
suggestions: null,
|
||||
});
|
||||
builder.errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
category: 'Could not find binding',
|
||||
description: `[BuildHIR] Could not find binding for param \`${param.node.name}\``,
|
||||
severity: ErrorSeverity.Invariant,
|
||||
suggestions: null,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc: param.node.loc ?? null,
|
||||
message: 'Could not find binding',
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const place: Place = {
|
||||
@@ -163,12 +170,18 @@ export function lower(
|
||||
'Assignment',
|
||||
);
|
||||
} else {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lower) Handle ${param.node.type} params`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
loc: param.node.loc ?? null,
|
||||
suggestions: null,
|
||||
});
|
||||
builder.errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
category: `Handle ${param.node.type} parameters`,
|
||||
description: `[BuildHIR] Add support for ${param.node.type} parameters`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
suggestions: null,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc: param.node.loc ?? null,
|
||||
message: 'Unsupported parameter type',
|
||||
}),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -188,13 +201,18 @@ export function lower(
|
||||
lowerStatement(builder, body);
|
||||
directives = body.get('directives').map(d => d.node.value.value);
|
||||
} else {
|
||||
builder.errors.push({
|
||||
severity: ErrorSeverity.InvalidJS,
|
||||
reason: `Unexpected function body kind`,
|
||||
description: `Expected function body to be an expression or a block statement, got \`${body.type}\``,
|
||||
loc: body.node.loc ?? null,
|
||||
suggestions: null,
|
||||
});
|
||||
builder.errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
severity: ErrorSeverity.InvalidJS,
|
||||
category: `Unexpected function body kind`,
|
||||
description: `Expected function body to be an expression or a block statement, got \`${body.type}\``,
|
||||
suggestions: null,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc: body.node.loc ?? null,
|
||||
message: 'Expected a block statement or expression',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (builder.errors.hasErrors()) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {CompilerError, Effect} from '..';
|
||||
import {CompilerDiagnostic, CompilerError, Effect, ErrorSeverity} from '..';
|
||||
import {HIRFunction, IdentifierId, Place} from '../HIR';
|
||||
import {
|
||||
eachInstructionLValue,
|
||||
@@ -28,16 +28,19 @@ export function validateLocalsNotReassignedAfterRender(fn: HIRFunction): void {
|
||||
false,
|
||||
);
|
||||
if (reassignment !== null) {
|
||||
CompilerError.throwInvalidReact({
|
||||
reason:
|
||||
'Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead',
|
||||
description:
|
||||
reassignment.identifier.name !== null &&
|
||||
reassignment.identifier.name.kind === 'named'
|
||||
? `Variable \`${reassignment.identifier.name.value}\` cannot be reassigned after render`
|
||||
: '',
|
||||
loc: reassignment.loc,
|
||||
});
|
||||
const errors = new CompilerError();
|
||||
errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
category: 'Cannot reassign a variable after render completes',
|
||||
description: `Reassigning ${reassignment.identifier.name != null && reassignment.identifier.name.kind === 'named' ? `variable \`${reassignment.identifier.name.value}\`` : 'a variable'} after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead`,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc: reassignment.loc,
|
||||
message: 'Cannot reassign variable after render completes',
|
||||
}),
|
||||
);
|
||||
throw errors;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {CompilerError, Effect, ErrorSeverity} from '..';
|
||||
import {CompilerDiagnostic, CompilerError, Effect, ErrorSeverity} from '..';
|
||||
import {
|
||||
FunctionEffect,
|
||||
HIRFunction,
|
||||
@@ -57,16 +57,24 @@ export function validateNoFreezingKnownMutableFunctions(
|
||||
if (operand.effect === Effect.Freeze) {
|
||||
const effect = contextMutationEffects.get(operand.identifier.id);
|
||||
if (effect != null) {
|
||||
errors.push({
|
||||
reason: `This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead`,
|
||||
loc: operand.loc,
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
});
|
||||
errors.push({
|
||||
reason: `The function modifies a local variable here`,
|
||||
loc: effect.loc,
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
});
|
||||
errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
category: 'Cannot modify local variables after render completes',
|
||||
description: `This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead`,
|
||||
})
|
||||
.withDetail({
|
||||
kind: 'error',
|
||||
loc: operand.loc,
|
||||
message:
|
||||
'This function may (indirectly) reassign or modify local variables after render',
|
||||
})
|
||||
.withDetail({
|
||||
kind: 'error',
|
||||
loc: effect.loc,
|
||||
message: 'This modifies a local variable',
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {CompilerError, ErrorSeverity} from '..';
|
||||
import {CompilerDiagnostic, CompilerError, ErrorSeverity} from '..';
|
||||
import {HIRFunction} from '../HIR';
|
||||
import {getFunctionCallSignature} from '../Inference/InferReferenceEffects';
|
||||
import {Result} from '../Utils/Result';
|
||||
@@ -34,17 +34,22 @@ export function validateNoImpureFunctionsInRender(
|
||||
callee.identifier.type,
|
||||
);
|
||||
if (signature != null && signature.impure === true) {
|
||||
errors.push({
|
||||
reason:
|
||||
'Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)',
|
||||
description:
|
||||
signature.canonicalName != null
|
||||
? `\`${signature.canonicalName}\` is an impure function whose results may change on every call`
|
||||
: null,
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
loc: callee.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
category: 'Cannot call impure function during render',
|
||||
description:
|
||||
(signature.canonicalName != null
|
||||
? `\`${signature.canonicalName}\` is an impure function. `
|
||||
: '') +
|
||||
'Calling an impure function can produce unstable results that update unpredictably when the component happens to re-render. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)',
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
suggestions: null,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc: callee.loc,
|
||||
message: 'Cannot call impure function',
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {CompilerError, ErrorSeverity} from '..';
|
||||
import {CompilerDiagnostic, CompilerError, ErrorSeverity} from '..';
|
||||
import {BlockId, HIRFunction} from '../HIR';
|
||||
import {Result} from '../Utils/Result';
|
||||
import {retainWhere} from '../Utils/utils';
|
||||
@@ -34,11 +34,17 @@ export function validateNoJSXInTryStatement(
|
||||
switch (value.kind) {
|
||||
case 'JsxExpression':
|
||||
case 'JsxFragment': {
|
||||
errors.push({
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
reason: `Unexpected JSX element within a try statement. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)`,
|
||||
loc: value.loc,
|
||||
});
|
||||
errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
category: 'Avoid constructing JSX within try/catch',
|
||||
description: `React does not immediately render components when JSX is rendered, so any errors from this component will not be caught by the try/catch. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)`,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc: value.loc,
|
||||
message: 'Avoid constructing JSX within try/catch',
|
||||
}),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {CompilerError, ErrorSeverity} from '../CompilerError';
|
||||
import {
|
||||
CompilerDiagnostic,
|
||||
CompilerError,
|
||||
ErrorSeverity,
|
||||
} from '../CompilerError';
|
||||
import {
|
||||
HIRFunction,
|
||||
IdentifierId,
|
||||
@@ -90,14 +94,21 @@ export function validateNoSetStateInEffects(
|
||||
if (arg !== undefined && arg.kind === 'Identifier') {
|
||||
const setState = setStateFunctions.get(arg.identifier.id);
|
||||
if (setState !== undefined) {
|
||||
errors.push({
|
||||
reason:
|
||||
'Calling setState directly within a useEffect causes cascading renders and is not recommended. Consider alternatives to useEffect. (https://react.dev/learn/you-might-not-need-an-effect)',
|
||||
description: null,
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
loc: setState.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
category:
|
||||
'Calling setState within an effect can trigger cascading renders',
|
||||
description:
|
||||
'Calling setState directly within a useEffect causes cascading renders that can hurt performance, and is not recommended. Consider alternatives to useEffect. (https://react.dev/learn/you-might-not-need-an-effect)',
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
suggestions: null,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc: setState.loc,
|
||||
message:
|
||||
'Avoid calling setState() in the top-level of an effect',
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {CompilerError, ErrorSeverity} from '../CompilerError';
|
||||
import {
|
||||
CompilerDiagnostic,
|
||||
CompilerError,
|
||||
ErrorSeverity,
|
||||
} from '../CompilerError';
|
||||
import {HIRFunction, IdentifierId, isSetStateType} from '../HIR';
|
||||
import {computeUnconditionalBlocks} from '../HIR/ComputeUnconditionalBlocks';
|
||||
import {eachInstructionValueOperand} from '../HIR/visitors';
|
||||
@@ -122,23 +126,35 @@ function validateNoSetStateInRenderImpl(
|
||||
unconditionalSetStateFunctions.has(callee.identifier.id)
|
||||
) {
|
||||
if (activeManualMemoId !== null) {
|
||||
errors.push({
|
||||
reason:
|
||||
'Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)',
|
||||
description: null,
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
loc: callee.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
category:
|
||||
'Calling setState from useMemo may trigger an infinite loop',
|
||||
description:
|
||||
'Each time the memo callback is evaluated it will change state. This can cause a memoization dependency to change, running the memo function again and causing an infinite loop. Instead of setting state in useMemo(), prefer deriving the value during render. (https://react.dev/reference/react/useState)',
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
suggestions: null,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc: callee.loc,
|
||||
message: 'Found setState() within useMemo()',
|
||||
}),
|
||||
);
|
||||
} else if (unconditionalBlocks.has(block.id)) {
|
||||
errors.push({
|
||||
reason:
|
||||
'This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)',
|
||||
description: null,
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
loc: callee.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
category:
|
||||
'Calling setState during render may trigger an infinite loop',
|
||||
description:
|
||||
'Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)',
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
suggestions: null,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc: callee.loc,
|
||||
message: 'Found setState() within useMemo()',
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {CompilerError, ErrorSeverity} from '..';
|
||||
import {
|
||||
CompilerDiagnostic,
|
||||
CompilerError,
|
||||
ErrorSeverity,
|
||||
} from '../CompilerError';
|
||||
import {FunctionExpression, HIRFunction, IdentifierId} from '../HIR';
|
||||
import {Result} from '../Utils/Result';
|
||||
|
||||
@@ -63,24 +67,41 @@ export function validateUseMemo(fn: HIRFunction): Result<void, CompilerError> {
|
||||
}
|
||||
|
||||
if (body.loweredFunc.func.params.length > 0) {
|
||||
errors.push({
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
reason: 'useMemo callbacks may not accept any arguments',
|
||||
description: null,
|
||||
loc: body.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
const firstParam = body.loweredFunc.func.params[0];
|
||||
const loc =
|
||||
firstParam.kind === 'Identifier'
|
||||
? firstParam.loc
|
||||
: firstParam.place.loc;
|
||||
errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
category: 'useMemo() callbacks may not accept parameters',
|
||||
description:
|
||||
'useMemo() callbacks are called by React to cache calculations across re-renders. They should not take parameters. Instead, directly reference the props, state, or local variables needed for the computation.',
|
||||
suggestions: null,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc,
|
||||
message: '',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (body.loweredFunc.func.async || body.loweredFunc.func.generator) {
|
||||
errors.push({
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
reason:
|
||||
'useMemo callbacks may not be async or generator functions',
|
||||
description: null,
|
||||
loc: body.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
errors.pushDiagnostic(
|
||||
CompilerDiagnostic.create({
|
||||
severity: ErrorSeverity.InvalidReact,
|
||||
category:
|
||||
'useMemo callbacks may not be async or generator functions',
|
||||
description:
|
||||
'useMemo() callbacks are called once and must synchronously return a value',
|
||||
suggestions: null,
|
||||
}).withDetail({
|
||||
kind: 'error',
|
||||
loc: body.loc,
|
||||
message: 'Async and generator functions are not supported',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -36,8 +36,10 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Found 1 error:
|
||||
Error: Cannot modify local variables after render completes
|
||||
|
||||
This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.bug-old-inference-false-positive-ref-validation-in-use-effect.ts:20:12
|
||||
18 | );
|
||||
@@ -51,24 +53,19 @@ error.bug-old-inference-false-positive-ref-validation-in-use-effect.ts:20:12
|
||||
> 23 | }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 24 | }, [update]);
|
||||
| ^^^^ This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^ This function may (indirectly) reassign or modify local variables after render
|
||||
25 |
|
||||
26 | return 'ok';
|
||||
27 | }
|
||||
|
||||
|
||||
Error: The function modifies a local variable here
|
||||
|
||||
error.bug-old-inference-false-positive-ref-validation-in-use-effect.ts:14:6
|
||||
12 | ...partialParams,
|
||||
13 | };
|
||||
> 14 | nextParams.param = 'value';
|
||||
| ^^^^^^^^^^ The function modifies a local variable here
|
||||
| ^^^^^^^^^^ This modifies a local variable
|
||||
15 | console.log(nextParams);
|
||||
16 | },
|
||||
17 | [params]
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -29,20 +29,18 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `x` cannot be reassigned after render.
|
||||
Reassigning variable `x` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.context-variable-only-chained-assign.ts:10:19
|
||||
8 | };
|
||||
9 | const fn2 = () => {
|
||||
> 10 | const copy2 = (x = 4);
|
||||
| ^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^ Cannot reassign variable after render completes
|
||||
11 | return [invoke(fn1), copy2, identity(copy2)];
|
||||
12 | };
|
||||
13 | return invoke(fn2);
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,20 +18,18 @@ function Component() {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `x` cannot be reassigned after render.
|
||||
Reassigning variable `x` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.declare-reassign-variable-in-function-declaration.ts:4:4
|
||||
2 | let x = null;
|
||||
3 | function foo() {
|
||||
> 4 | x = 9;
|
||||
| ^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^ Cannot reassign variable after render completes
|
||||
5 | }
|
||||
6 | const y = bar(foo);
|
||||
7 | return <Child y={y} />;
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,20 +16,18 @@ function Component() {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `callback` cannot be reassigned after render.
|
||||
Reassigning variable `callback` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.function-expression-references-variable-its-assigned-to.ts:3:4
|
||||
1 | function Component() {
|
||||
2 | let callback = () => {
|
||||
> 3 | callback = null;
|
||||
| ^^^^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^^^^ Cannot reassign variable after render completes
|
||||
4 | };
|
||||
5 | return <div onClick={callback} />;
|
||||
6 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ function component(a, b) {
|
||||
Found 1 error:
|
||||
Error: useMemo callbacks may not be async or generator functions
|
||||
|
||||
useMemo() callbacks are called once and must synchronously return a value
|
||||
|
||||
error.invalid-ReactUseMemo-async-callback.ts:2:24
|
||||
1 | function component(a, b) {
|
||||
> 2 | let x = React.useMemo(async () => {
|
||||
@@ -25,12 +27,10 @@ error.invalid-ReactUseMemo-async-callback.ts:2:24
|
||||
> 3 | await a;
|
||||
| ^^^^^^^^^^^^
|
||||
> 4 | }, []);
|
||||
| ^^^^ useMemo callbacks may not be async or generator functions
|
||||
| ^^^^ Async and generator functions are not supported
|
||||
5 | return x;
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -23,30 +23,30 @@ function Component({item, cond}) {
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Error: Calling setState from useMemo may trigger an infinite loop
|
||||
|
||||
Each time the memo callback is evaluated it will change state. This can cause a memoization dependency to change, running the memo function again and causing an infinite loop. Instead of setting state in useMemo(), prefer deriving the value during render. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.invalid-conditional-setState-in-useMemo.ts:7:6
|
||||
5 | useMemo(() => {
|
||||
6 | if (cond) {
|
||||
> 7 | setPrevItem(item);
|
||||
| ^^^^^^^^^^^ Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^^^^^^^^^ Found setState() within useMemo()
|
||||
8 | setState(0);
|
||||
9 | }
|
||||
10 | }, [cond, key, init]);
|
||||
Error: Calling setState from useMemo may trigger an infinite loop
|
||||
|
||||
|
||||
Error: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Each time the memo callback is evaluated it will change state. This can cause a memoization dependency to change, running the memo function again and causing an infinite loop. Instead of setting state in useMemo(), prefer deriving the value during render. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.invalid-conditional-setState-in-useMemo.ts:8:6
|
||||
6 | if (cond) {
|
||||
7 | setPrevItem(item);
|
||||
> 8 | setState(0);
|
||||
| ^^^^^^^^ Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^^^^^^ Found setState() within useMemo()
|
||||
9 | }
|
||||
10 | }, [cond, key, init]);
|
||||
11 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -17,8 +17,10 @@ function useFoo() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Found 1 error:
|
||||
Error: Cannot modify local variables after render completes
|
||||
|
||||
This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-hook-function-argument-mutates-local-variable.ts:5:10
|
||||
3 | function useFoo() {
|
||||
@@ -28,23 +30,18 @@ error.invalid-hook-function-argument-mutates-local-variable.ts:5:10
|
||||
> 6 | cache.set('key', 'value');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 7 | });
|
||||
| ^^^^ This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^ This function may (indirectly) reassign or modify local variables after render
|
||||
8 | }
|
||||
9 |
|
||||
|
||||
|
||||
Error: The function modifies a local variable here
|
||||
|
||||
error.invalid-hook-function-argument-mutates-local-variable.ts:6:4
|
||||
4 | const cache = new Map();
|
||||
5 | useHook(() => {
|
||||
> 6 | cache.set('key', 'value');
|
||||
| ^^^^^ The function modifies a local variable here
|
||||
| ^^^^^ This modifies a local variable
|
||||
7 | });
|
||||
8 | }
|
||||
9 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -47,20 +47,18 @@ function Component() {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `local` cannot be reassigned after render.
|
||||
Reassigning variable `local` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-nested-function-reassign-local-variable-in-effect.ts:7:6
|
||||
5 | // Create the reassignment function inside another function, then return it
|
||||
6 | const reassignLocal = newValue => {
|
||||
> 7 | local = newValue;
|
||||
| ^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^ Cannot reassign variable after render completes
|
||||
8 | };
|
||||
9 | return reassignLocal;
|
||||
10 | };
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -17,30 +17,27 @@ function Component() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Found 1 error:
|
||||
Error: Cannot modify local variables after render completes
|
||||
|
||||
This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-pass-mutable-function-as-prop.ts:7:18
|
||||
5 | cache.set('key', 'value');
|
||||
6 | };
|
||||
> 7 | return <Foo fn={fn} />;
|
||||
| ^^ This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^ This function may (indirectly) reassign or modify local variables after render
|
||||
8 | }
|
||||
9 |
|
||||
|
||||
|
||||
Error: The function modifies a local variable here
|
||||
|
||||
error.invalid-pass-mutable-function-as-prop.ts:5:4
|
||||
3 | const cache = new Map();
|
||||
4 | const fn = () => {
|
||||
> 5 | cache.set('key', 'value');
|
||||
| ^^^^^ The function modifies a local variable here
|
||||
| ^^^^^ This modifies a local variable
|
||||
6 | };
|
||||
7 | return <Foo fn={fn} />;
|
||||
8 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -16,20 +16,18 @@ function useFoo() {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `x` cannot be reassigned after render.
|
||||
Reassigning variable `x` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-reassign-local-in-hook-return-value.ts:4:4
|
||||
2 | let x = 0;
|
||||
3 | return value => {
|
||||
> 4 | x = value;
|
||||
| ^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^ Cannot reassign variable after render completes
|
||||
5 | };
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -48,20 +48,18 @@ function Component() {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `local` cannot be reassigned after render.
|
||||
Reassigning variable `local` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-reassign-local-variable-in-effect.ts:7:4
|
||||
5 |
|
||||
6 | const reassignLocal = newValue => {
|
||||
> 7 | local = newValue;
|
||||
| ^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^ Cannot reassign variable after render completes
|
||||
8 | };
|
||||
9 |
|
||||
10 | const onMount = newValue => {
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -49,20 +49,18 @@ function Component() {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `local` cannot be reassigned after render.
|
||||
Reassigning variable `local` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-reassign-local-variable-in-hook-argument.ts:8:4
|
||||
6 |
|
||||
7 | const reassignLocal = newValue => {
|
||||
> 8 | local = newValue;
|
||||
| ^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^ Cannot reassign variable after render completes
|
||||
9 | };
|
||||
10 |
|
||||
11 | const callback = newValue => {
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -42,20 +42,18 @@ function Component() {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `local` cannot be reassigned after render.
|
||||
Reassigning variable `local` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-reassign-local-variable-in-jsx-callback.ts:5:4
|
||||
3 |
|
||||
4 | const reassignLocal = newValue => {
|
||||
> 5 | local = newValue;
|
||||
| ^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^ Cannot reassign variable after render completes
|
||||
6 | };
|
||||
7 |
|
||||
8 | const onClick = newValue => {
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ function useFoo() {
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Found 1 error:
|
||||
Error: Cannot modify local variables after render completes
|
||||
|
||||
This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-return-mutable-function-from-hook.ts:7:9
|
||||
5 | useHook(); // for inference to kick in
|
||||
@@ -30,23 +32,18 @@ error.invalid-return-mutable-function-from-hook.ts:7:9
|
||||
> 8 | cache.set('key', 'value');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 9 | };
|
||||
| ^^^^ This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^ This function may (indirectly) reassign or modify local variables after render
|
||||
10 | }
|
||||
11 |
|
||||
|
||||
|
||||
Error: The function modifies a local variable here
|
||||
|
||||
error.invalid-return-mutable-function-from-hook.ts:8:4
|
||||
6 | const cache = new Map();
|
||||
7 | return () => {
|
||||
> 8 | cache.set('key', 'value');
|
||||
| ^^^^^ The function modifies a local variable here
|
||||
| ^^^^^ This modifies a local variable
|
||||
9 | };
|
||||
10 | }
|
||||
11 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -27,18 +27,18 @@ function useKeyedState({key, init}) {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Error: Calling setState from useMemo may trigger an infinite loop
|
||||
|
||||
Each time the memo callback is evaluated it will change state. This can cause a memoization dependency to change, running the memo function again and causing an infinite loop. Instead of setting state in useMemo(), prefer deriving the value during render. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.invalid-setState-in-useMemo-indirect-useCallback.ts:13:4
|
||||
11 |
|
||||
12 | useMemo(() => {
|
||||
> 13 | fn();
|
||||
| ^^ Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^ Found setState() within useMemo()
|
||||
14 | }, [key, init]);
|
||||
15 |
|
||||
16 | return state;
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -21,30 +21,30 @@ function useKeyedState({key, init}) {
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Error: Calling setState from useMemo may trigger an infinite loop
|
||||
|
||||
Each time the memo callback is evaluated it will change state. This can cause a memoization dependency to change, running the memo function again and causing an infinite loop. Instead of setting state in useMemo(), prefer deriving the value during render. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.invalid-setState-in-useMemo.ts:6:4
|
||||
4 |
|
||||
5 | useMemo(() => {
|
||||
> 6 | setPrevKey(key);
|
||||
| ^^^^^^^^^^ Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^^^^^^^^ Found setState() within useMemo()
|
||||
7 | setState(init);
|
||||
8 | }, [key, init]);
|
||||
9 |
|
||||
Error: Calling setState from useMemo may trigger an infinite loop
|
||||
|
||||
|
||||
Error: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Each time the memo callback is evaluated it will change state. This can cause a memoization dependency to change, running the memo function again and causing an infinite loop. Instead of setting state in useMemo(), prefer deriving the value during render. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.invalid-setState-in-useMemo.ts:7:4
|
||||
5 | useMemo(() => {
|
||||
6 | setPrevKey(key);
|
||||
> 7 | setState(init);
|
||||
| ^^^^^^^^ Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^^^^^^ Found setState() within useMemo()
|
||||
8 | }, [key, init]);
|
||||
9 |
|
||||
10 | return state;
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -47,8 +47,10 @@ hook useMemoMap<TInput: interface {}, TOutput>(
|
||||
## Error
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Found 1 error:
|
||||
Error: Cannot modify local variables after render completes
|
||||
|
||||
This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
undefined:21:9
|
||||
19 | map: TInput => TOutput
|
||||
@@ -86,23 +88,18 @@ undefined:21:9
|
||||
> 36 | };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 37 | }, [map]);
|
||||
| ^^^^^^^^^^^^ This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^^^^^^^^ This function may (indirectly) reassign or modify local variables after render
|
||||
38 | }
|
||||
39 |
|
||||
|
||||
|
||||
Error: The function modifies a local variable here
|
||||
|
||||
undefined:33:8
|
||||
31 | if (output == null) {
|
||||
32 | output = map(input);
|
||||
> 33 | cache.set(input, output);
|
||||
| ^^^^^ The function modifies a local variable here
|
||||
| ^^^^^ This modifies a local variable
|
||||
34 | }
|
||||
35 | return output;
|
||||
36 | };
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -20,30 +20,30 @@ function Component(props) {
|
||||
|
||||
```
|
||||
Found 2 errors:
|
||||
Error: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Error: Calling setState during render may trigger an infinite loop
|
||||
|
||||
Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.invalid-unconditional-set-state-in-render.ts:6:2
|
||||
4 | const aliased = setX;
|
||||
5 |
|
||||
> 6 | setX(1);
|
||||
| ^^^^ This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^^ Found setState() within useMemo()
|
||||
7 | aliased(2);
|
||||
8 |
|
||||
9 | return x;
|
||||
Error: Calling setState during render may trigger an infinite loop
|
||||
|
||||
|
||||
Error: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.invalid-unconditional-set-state-in-render.ts:7:2
|
||||
5 |
|
||||
6 | setX(1);
|
||||
> 7 | aliased(2);
|
||||
| ^^^^^^^ This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^^^^^ Found setState() within useMemo()
|
||||
8 |
|
||||
9 | return x;
|
||||
10 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ function component(a, b) {
|
||||
Found 1 error:
|
||||
Error: useMemo callbacks may not be async or generator functions
|
||||
|
||||
useMemo() callbacks are called once and must synchronously return a value
|
||||
|
||||
error.invalid-useMemo-async-callback.ts:2:18
|
||||
1 | function component(a, b) {
|
||||
> 2 | let x = useMemo(async () => {
|
||||
@@ -25,12 +27,10 @@ error.invalid-useMemo-async-callback.ts:2:18
|
||||
> 3 | await a;
|
||||
| ^^^^^^^^^^^^
|
||||
> 4 | }, []);
|
||||
| ^^^^ useMemo callbacks may not be async or generator functions
|
||||
| ^^^^ Async and generator functions are not supported
|
||||
5 | return x;
|
||||
6 | }
|
||||
7 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -14,17 +14,17 @@ function component(a, b) {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: useMemo callbacks may not accept any arguments
|
||||
Error: useMemo() callbacks may not accept parameters
|
||||
|
||||
useMemo() callbacks are called by React to cache calculations across re-renders. They should not take parameters. Instead, directly reference the props, state, or local variables needed for the computation.
|
||||
|
||||
error.invalid-useMemo-callback-args.ts:2:18
|
||||
1 | function component(a, b) {
|
||||
> 2 | let x = useMemo(c => a, []);
|
||||
| ^^^^^^ useMemo callbacks may not accept any arguments
|
||||
| ^
|
||||
3 | return x;
|
||||
4 | }
|
||||
5 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -33,20 +33,18 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `a` cannot be reassigned after render.
|
||||
Reassigning variable `a` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.mutable-range-shared-inner-outer-function.ts:8:6
|
||||
6 | const f = () => {
|
||||
7 | if (cond) {
|
||||
> 8 | a = {};
|
||||
| ^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^ Cannot reassign variable after render completes
|
||||
9 | b = [];
|
||||
10 | } else {
|
||||
11 | a = {};
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,20 +18,18 @@ function Component() {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `onClick` cannot be reassigned after render.
|
||||
Reassigning variable `onClick` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.todo-function-expression-references-later-variable-declaration.ts:3:4
|
||||
1 | function Component() {
|
||||
2 | let callback = () => {
|
||||
> 3 | onClick = () => {};
|
||||
| ^^^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^^^ Cannot reassign variable after render completes
|
||||
4 | };
|
||||
5 | let onClick;
|
||||
6 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -23,18 +23,18 @@ function Component(props) {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Error: Calling setState during render may trigger an infinite loop
|
||||
|
||||
Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.unconditional-set-state-in-render-after-loop-break.ts:11:2
|
||||
9 | }
|
||||
10 | }
|
||||
> 11 | setState(true);
|
||||
| ^^^^^^^^ This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^^^^^^ Found setState() within useMemo()
|
||||
12 | return state;
|
||||
13 | }
|
||||
14 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -18,18 +18,18 @@ function Component(props) {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Error: Calling setState during render may trigger an infinite loop
|
||||
|
||||
Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.unconditional-set-state-in-render-after-loop.ts:6:2
|
||||
4 | for (const _ of props) {
|
||||
5 | }
|
||||
> 6 | setState(true);
|
||||
| ^^^^^^^^ This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^^^^^^ Found setState() within useMemo()
|
||||
7 | return state;
|
||||
8 | }
|
||||
9 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -23,18 +23,18 @@ function Component(props) {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Error: Calling setState during render may trigger an infinite loop
|
||||
|
||||
Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.unconditional-set-state-in-render-with-loop-throw.ts:11:2
|
||||
9 | }
|
||||
10 | }
|
||||
> 11 | setState(true);
|
||||
| ^^^^^^^^ This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^^^^^^ Found setState() within useMemo()
|
||||
12 | return state;
|
||||
13 | }
|
||||
14 |
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -21,18 +21,18 @@ function Component(props) {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Error: Calling setState during render may trigger an infinite loop
|
||||
|
||||
Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.unconditional-set-state-lambda.ts:8:2
|
||||
6 | setX(1);
|
||||
7 | };
|
||||
> 8 | foo();
|
||||
| ^^^ This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^ Found setState() within useMemo()
|
||||
9 |
|
||||
10 | return [x];
|
||||
11 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -29,18 +29,18 @@ function Component(props) {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
Error: Calling setState during render may trigger an infinite loop
|
||||
|
||||
Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)
|
||||
|
||||
error.unconditional-set-state-nested-function-expressions.ts:16:2
|
||||
14 | bar();
|
||||
15 | };
|
||||
> 16 | baz();
|
||||
| ^^^ This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
||||
| ^^^ Found setState() within useMemo()
|
||||
17 |
|
||||
18 | return [x];
|
||||
19 | }
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ function Component(props) {
|
||||
## Logs
|
||||
|
||||
```
|
||||
{"kind":"CompileError","detail":{"options":{"reason":"Unexpected JSX element within a try statement. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)","description":null,"severity":"InvalidReact","loc":{"start":{"line":11,"column":11,"index":222},"end":{"line":11,"column":32,"index":243},"filename":"invalid-jsx-in-catch-in-outer-try-with-catch.ts"}}},"fnLoc":null}
|
||||
{"kind":"CompileError","detail":{"options":{"severity":"InvalidReact","category":"Avoid constructing JSX within try/catch","description":"React does not immediately render components when JSX is rendered, so any errors from this component will not be caught by the try/catch. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)","details":[{"kind":"error","loc":{"start":{"line":11,"column":11,"index":222},"end":{"line":11,"column":32,"index":243},"filename":"invalid-jsx-in-catch-in-outer-try-with-catch.ts"},"message":"Avoid constructing JSX within try/catch"}]}},"fnLoc":null}
|
||||
{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":91},"end":{"line":17,"column":1,"index":298},"filename":"invalid-jsx-in-catch-in-outer-try-with-catch.ts"},"fnName":"Component","memoSlots":4,"memoBlocks":2,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0}
|
||||
```
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ function Component(props) {
|
||||
## Logs
|
||||
|
||||
```
|
||||
{"kind":"CompileError","detail":{"options":{"reason":"Unexpected JSX element within a try statement. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)","description":null,"severity":"InvalidReact","loc":{"start":{"line":5,"column":9,"index":104},"end":{"line":5,"column":16,"index":111},"filename":"invalid-jsx-in-try-with-catch.ts"}}},"fnLoc":null}
|
||||
{"kind":"CompileError","detail":{"options":{"severity":"InvalidReact","category":"Avoid constructing JSX within try/catch","description":"React does not immediately render components when JSX is rendered, so any errors from this component will not be caught by the try/catch. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)","details":[{"kind":"error","loc":{"start":{"line":5,"column":9,"index":104},"end":{"line":5,"column":16,"index":111},"filename":"invalid-jsx-in-try-with-catch.ts"},"message":"Avoid constructing JSX within try/catch"}]}},"fnLoc":null}
|
||||
{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":49},"end":{"line":10,"column":1,"index":160},"filename":"invalid-jsx-in-try-with-catch.ts"},"fnName":"Component","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0}
|
||||
```
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ function _temp(s) {
|
||||
## Logs
|
||||
|
||||
```
|
||||
{"kind":"CompileError","detail":{"options":{"reason":"Calling setState directly within a useEffect causes cascading renders and is not recommended. Consider alternatives to useEffect. (https://react.dev/learn/you-might-not-need-an-effect)","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":13,"column":4,"index":265},"end":{"line":13,"column":5,"index":266},"filename":"invalid-setState-in-useEffect-transitive.ts","identifierName":"g"}}},"fnLoc":null}
|
||||
{"kind":"CompileError","detail":{"options":{"category":"Calling setState within an effect can trigger cascading renders","description":"Calling setState directly within a useEffect causes cascading renders that can hurt performance, and is not recommended. Consider alternatives to useEffect. (https://react.dev/learn/you-might-not-need-an-effect)","severity":"InvalidReact","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":13,"column":4,"index":265},"end":{"line":13,"column":5,"index":266},"filename":"invalid-setState-in-useEffect-transitive.ts","identifierName":"g"},"message":"Avoid calling setState() in the top-level of an effect"}]}},"fnLoc":null}
|
||||
{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":92},"end":{"line":16,"column":1,"index":293},"filename":"invalid-setState-in-useEffect-transitive.ts"},"fnName":"Component","memoSlots":2,"memoBlocks":2,"memoValues":2,"prunedMemoBlocks":0,"prunedMemoValues":0}
|
||||
```
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ function _temp(s) {
|
||||
## Logs
|
||||
|
||||
```
|
||||
{"kind":"CompileError","detail":{"options":{"reason":"Calling setState directly within a useEffect causes cascading renders and is not recommended. Consider alternatives to useEffect. (https://react.dev/learn/you-might-not-need-an-effect)","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":7,"column":4,"index":180},"end":{"line":7,"column":12,"index":188},"filename":"invalid-setState-in-useEffect.ts","identifierName":"setState"}}},"fnLoc":null}
|
||||
{"kind":"CompileError","detail":{"options":{"category":"Calling setState within an effect can trigger cascading renders","description":"Calling setState directly within a useEffect causes cascading renders that can hurt performance, and is not recommended. Consider alternatives to useEffect. (https://react.dev/learn/you-might-not-need-an-effect)","severity":"InvalidReact","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":7,"column":4,"index":180},"end":{"line":7,"column":12,"index":188},"filename":"invalid-setState-in-useEffect.ts","identifierName":"setState"},"message":"Avoid calling setState() in the top-level of an effect"}]}},"fnLoc":null}
|
||||
{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":92},"end":{"line":10,"column":1,"index":225},"filename":"invalid-setState-in-useEffect.ts"},"fnName":"Component","memoSlots":1,"memoBlocks":1,"memoValues":1,"prunedMemoBlocks":0,"prunedMemoValues":0}
|
||||
```
|
||||
|
||||
|
||||
@@ -43,20 +43,18 @@ function Component() {
|
||||
|
||||
```
|
||||
Found 1 error:
|
||||
Error: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
Error: Cannot reassign a variable after render completes
|
||||
|
||||
Variable `local` cannot be reassigned after render.
|
||||
Reassigning variable `local` after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
|
||||
error.invalid-reassign-local-variable-in-jsx-callback.ts:6:4
|
||||
4 |
|
||||
5 | const reassignLocal = newValue => {
|
||||
> 6 | local = newValue;
|
||||
| ^^^^^ Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead
|
||||
| ^^^^^ Cannot reassign variable after render completes
|
||||
7 | };
|
||||
8 |
|
||||
9 | const onClick = newValue => {
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user