Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2283eb9183 |
@@ -59,7 +59,7 @@ export type CompilerDiagnosticDetail =
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
kind: 'error';
|
kind: 'error';
|
||||||
loc: SourceLocation;
|
loc: SourceLocation | null;
|
||||||
message: string;
|
message: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,6 +100,12 @@ export class CompilerDiagnostic {
|
|||||||
this.options = options;
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static create(
|
||||||
|
options: Omit<CompilerDiagnosticOptions, 'details'>,
|
||||||
|
): CompilerDiagnostic {
|
||||||
|
return new CompilerDiagnostic({...options, details: []});
|
||||||
|
}
|
||||||
|
|
||||||
get category(): CompilerDiagnosticOptions['category'] {
|
get category(): CompilerDiagnosticOptions['category'] {
|
||||||
return this.options.category;
|
return this.options.category;
|
||||||
}
|
}
|
||||||
@@ -113,6 +119,11 @@ export class CompilerDiagnostic {
|
|||||||
return this.options.suggestions;
|
return this.options.suggestions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
withDetail(detail: CompilerDiagnosticDetail): CompilerDiagnostic {
|
||||||
|
this.options.details.push(detail);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
primaryLocation(): SourceLocation | null {
|
primaryLocation(): SourceLocation | null {
|
||||||
return this.options.details.filter(d => d.kind === 'error')[0]?.loc ?? null;
|
return this.options.details.filter(d => d.kind === 'error')[0]?.loc ?? null;
|
||||||
}
|
}
|
||||||
@@ -127,7 +138,7 @@ export class CompilerDiagnostic {
|
|||||||
switch (detail.kind) {
|
switch (detail.kind) {
|
||||||
case 'error': {
|
case 'error': {
|
||||||
const loc = detail.loc;
|
const loc = detail.loc;
|
||||||
if (typeof loc === 'symbol') {
|
if (loc == null || typeof loc === 'symbol') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let codeFrame: string;
|
let codeFrame: string;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {NodePath, Scope} from '@babel/traverse';
|
|||||||
import * as t from '@babel/types';
|
import * as t from '@babel/types';
|
||||||
import invariant from 'invariant';
|
import invariant from 'invariant';
|
||||||
import {
|
import {
|
||||||
|
CompilerDiagnostic,
|
||||||
CompilerError,
|
CompilerError,
|
||||||
CompilerSuggestionOperation,
|
CompilerSuggestionOperation,
|
||||||
ErrorSeverity,
|
ErrorSeverity,
|
||||||
@@ -104,12 +105,18 @@ export function lower(
|
|||||||
if (param.isIdentifier()) {
|
if (param.isIdentifier()) {
|
||||||
const binding = builder.resolveIdentifier(param);
|
const binding = builder.resolveIdentifier(param);
|
||||||
if (binding.kind !== 'Identifier') {
|
if (binding.kind !== 'Identifier') {
|
||||||
builder.errors.push({
|
builder.errors.pushDiagnostic(
|
||||||
reason: `(BuildHIR::lower) Could not find binding for param \`${param.node.name}\``,
|
CompilerDiagnostic.create({
|
||||||
severity: ErrorSeverity.Invariant,
|
category: 'Could not find binding',
|
||||||
loc: param.node.loc ?? null,
|
description: `[BuildHIR] Could not find binding for param \`${param.node.name}\``,
|
||||||
suggestions: null,
|
severity: ErrorSeverity.Invariant,
|
||||||
});
|
suggestions: null,
|
||||||
|
}).withDetail({
|
||||||
|
kind: 'error',
|
||||||
|
loc: param.node.loc ?? null,
|
||||||
|
message: 'Could not find binding',
|
||||||
|
}),
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const place: Place = {
|
const place: Place = {
|
||||||
@@ -163,12 +170,18 @@ export function lower(
|
|||||||
'Assignment',
|
'Assignment',
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
builder.errors.push({
|
builder.errors.pushDiagnostic(
|
||||||
reason: `(BuildHIR::lower) Handle ${param.node.type} params`,
|
CompilerDiagnostic.create({
|
||||||
severity: ErrorSeverity.Todo,
|
category: `Handle ${param.node.type} parameters`,
|
||||||
loc: param.node.loc ?? null,
|
description: `[BuildHIR] Add support for ${param.node.type} parameters`,
|
||||||
suggestions: null,
|
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);
|
lowerStatement(builder, body);
|
||||||
directives = body.get('directives').map(d => d.node.value.value);
|
directives = body.get('directives').map(d => d.node.value.value);
|
||||||
} else {
|
} else {
|
||||||
builder.errors.push({
|
builder.errors.pushDiagnostic(
|
||||||
severity: ErrorSeverity.InvalidJS,
|
CompilerDiagnostic.create({
|
||||||
reason: `Unexpected function body kind`,
|
severity: ErrorSeverity.InvalidJS,
|
||||||
description: `Expected function body to be an expression or a block statement, got \`${body.type}\``,
|
category: `Unexpected function body kind`,
|
||||||
loc: body.node.loc ?? null,
|
description: `Expected function body to be an expression or a block statement, got \`${body.type}\``,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
}).withDetail({
|
||||||
|
kind: 'error',
|
||||||
|
loc: body.node.loc ?? null,
|
||||||
|
message: 'Expected a block statement or expression',
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builder.errors.hasErrors()) {
|
if (builder.errors.hasErrors()) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* LICENSE file in the root directory of this source tree.
|
* 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 {HIRFunction, IdentifierId, Place} from '../HIR';
|
||||||
import {
|
import {
|
||||||
eachInstructionLValue,
|
eachInstructionLValue,
|
||||||
@@ -28,16 +28,19 @@ export function validateLocalsNotReassignedAfterRender(fn: HIRFunction): void {
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
if (reassignment !== null) {
|
if (reassignment !== null) {
|
||||||
CompilerError.throwInvalidReact({
|
const errors = new CompilerError();
|
||||||
reason:
|
errors.pushDiagnostic(
|
||||||
'Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead',
|
CompilerDiagnostic.create({
|
||||||
description:
|
severity: ErrorSeverity.InvalidReact,
|
||||||
reassignment.identifier.name !== null &&
|
category: 'Cannot reassign a variable after render completes',
|
||||||
reassignment.identifier.name.kind === 'named'
|
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`,
|
||||||
? `Variable \`${reassignment.identifier.name.value}\` cannot be reassigned after render`
|
}).withDetail({
|
||||||
: '',
|
kind: 'error',
|
||||||
loc: reassignment.loc,
|
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.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {CompilerError, Effect, ErrorSeverity} from '..';
|
import {CompilerDiagnostic, CompilerError, Effect, ErrorSeverity} from '..';
|
||||||
import {
|
import {
|
||||||
FunctionEffect,
|
FunctionEffect,
|
||||||
HIRFunction,
|
HIRFunction,
|
||||||
@@ -57,16 +57,24 @@ export function validateNoFreezingKnownMutableFunctions(
|
|||||||
if (operand.effect === Effect.Freeze) {
|
if (operand.effect === Effect.Freeze) {
|
||||||
const effect = contextMutationEffects.get(operand.identifier.id);
|
const effect = contextMutationEffects.get(operand.identifier.id);
|
||||||
if (effect != null) {
|
if (effect != null) {
|
||||||
errors.push({
|
errors.pushDiagnostic(
|
||||||
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`,
|
CompilerDiagnostic.create({
|
||||||
loc: operand.loc,
|
severity: ErrorSeverity.InvalidReact,
|
||||||
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`,
|
||||||
errors.push({
|
})
|
||||||
reason: `The function modifies a local variable here`,
|
.withDetail({
|
||||||
loc: effect.loc,
|
kind: 'error',
|
||||||
severity: ErrorSeverity.InvalidReact,
|
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.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {CompilerError, ErrorSeverity} from '..';
|
import {CompilerDiagnostic, CompilerError, ErrorSeverity} from '..';
|
||||||
import {HIRFunction} from '../HIR';
|
import {HIRFunction} from '../HIR';
|
||||||
import {getFunctionCallSignature} from '../Inference/InferReferenceEffects';
|
import {getFunctionCallSignature} from '../Inference/InferReferenceEffects';
|
||||||
import {Result} from '../Utils/Result';
|
import {Result} from '../Utils/Result';
|
||||||
@@ -34,17 +34,22 @@ export function validateNoImpureFunctionsInRender(
|
|||||||
callee.identifier.type,
|
callee.identifier.type,
|
||||||
);
|
);
|
||||||
if (signature != null && signature.impure === true) {
|
if (signature != null && signature.impure === true) {
|
||||||
errors.push({
|
errors.pushDiagnostic(
|
||||||
reason:
|
CompilerDiagnostic.create({
|
||||||
'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)',
|
category: 'Cannot call impure function during render',
|
||||||
description:
|
description:
|
||||||
signature.canonicalName != null
|
(signature.canonicalName != null
|
||||||
? `\`${signature.canonicalName}\` is an impure function whose results may change on every call`
|
? `\`${signature.canonicalName}\` is an impure function. `
|
||||||
: null,
|
: '') +
|
||||||
severity: ErrorSeverity.InvalidReact,
|
'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)',
|
||||||
loc: callee.loc,
|
severity: ErrorSeverity.InvalidReact,
|
||||||
suggestions: null,
|
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.
|
* 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 {BlockId, HIRFunction} from '../HIR';
|
||||||
import {Result} from '../Utils/Result';
|
import {Result} from '../Utils/Result';
|
||||||
import {retainWhere} from '../Utils/utils';
|
import {retainWhere} from '../Utils/utils';
|
||||||
@@ -34,11 +34,17 @@ export function validateNoJSXInTryStatement(
|
|||||||
switch (value.kind) {
|
switch (value.kind) {
|
||||||
case 'JsxExpression':
|
case 'JsxExpression':
|
||||||
case 'JsxFragment': {
|
case 'JsxFragment': {
|
||||||
errors.push({
|
errors.pushDiagnostic(
|
||||||
severity: ErrorSeverity.InvalidReact,
|
CompilerDiagnostic.create({
|
||||||
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)`,
|
severity: ErrorSeverity.InvalidReact,
|
||||||
loc: value.loc,
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,11 @@
|
|||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {CompilerError, ErrorSeverity} from '../CompilerError';
|
import {
|
||||||
|
CompilerDiagnostic,
|
||||||
|
CompilerError,
|
||||||
|
ErrorSeverity,
|
||||||
|
} from '../CompilerError';
|
||||||
import {
|
import {
|
||||||
HIRFunction,
|
HIRFunction,
|
||||||
IdentifierId,
|
IdentifierId,
|
||||||
@@ -90,14 +94,21 @@ export function validateNoSetStateInEffects(
|
|||||||
if (arg !== undefined && arg.kind === 'Identifier') {
|
if (arg !== undefined && arg.kind === 'Identifier') {
|
||||||
const setState = setStateFunctions.get(arg.identifier.id);
|
const setState = setStateFunctions.get(arg.identifier.id);
|
||||||
if (setState !== undefined) {
|
if (setState !== undefined) {
|
||||||
errors.push({
|
errors.pushDiagnostic(
|
||||||
reason:
|
CompilerDiagnostic.create({
|
||||||
'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)',
|
category:
|
||||||
description: null,
|
'Calling setState within an effect can trigger cascading renders',
|
||||||
severity: ErrorSeverity.InvalidReact,
|
description:
|
||||||
loc: setState.loc,
|
'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)',
|
||||||
suggestions: null,
|
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.
|
* 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 {HIRFunction, IdentifierId, isSetStateType} from '../HIR';
|
||||||
import {computeUnconditionalBlocks} from '../HIR/ComputeUnconditionalBlocks';
|
import {computeUnconditionalBlocks} from '../HIR/ComputeUnconditionalBlocks';
|
||||||
import {eachInstructionValueOperand} from '../HIR/visitors';
|
import {eachInstructionValueOperand} from '../HIR/visitors';
|
||||||
@@ -122,23 +126,35 @@ function validateNoSetStateInRenderImpl(
|
|||||||
unconditionalSetStateFunctions.has(callee.identifier.id)
|
unconditionalSetStateFunctions.has(callee.identifier.id)
|
||||||
) {
|
) {
|
||||||
if (activeManualMemoId !== null) {
|
if (activeManualMemoId !== null) {
|
||||||
errors.push({
|
errors.pushDiagnostic(
|
||||||
reason:
|
CompilerDiagnostic.create({
|
||||||
'Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)',
|
category:
|
||||||
description: null,
|
'Calling setState from useMemo may trigger an infinite loop',
|
||||||
severity: ErrorSeverity.InvalidReact,
|
description:
|
||||||
loc: callee.loc,
|
'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)',
|
||||||
suggestions: null,
|
severity: ErrorSeverity.InvalidReact,
|
||||||
});
|
suggestions: null,
|
||||||
|
}).withDetail({
|
||||||
|
kind: 'error',
|
||||||
|
loc: callee.loc,
|
||||||
|
message: 'Found setState() within useMemo()',
|
||||||
|
}),
|
||||||
|
);
|
||||||
} else if (unconditionalBlocks.has(block.id)) {
|
} else if (unconditionalBlocks.has(block.id)) {
|
||||||
errors.push({
|
errors.pushDiagnostic(
|
||||||
reason:
|
CompilerDiagnostic.create({
|
||||||
'This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)',
|
category:
|
||||||
description: null,
|
'Calling setState during render may trigger an infinite loop',
|
||||||
severity: ErrorSeverity.InvalidReact,
|
description:
|
||||||
loc: callee.loc,
|
'Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)',
|
||||||
suggestions: null,
|
severity: ErrorSeverity.InvalidReact,
|
||||||
});
|
suggestions: null,
|
||||||
|
}).withDetail({
|
||||||
|
kind: 'error',
|
||||||
|
loc: callee.loc,
|
||||||
|
message: 'Found setState() within useMemo()',
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -5,7 +5,11 @@
|
|||||||
* LICENSE file in the root directory of this source tree.
|
* 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 {FunctionExpression, HIRFunction, IdentifierId} from '../HIR';
|
||||||
import {Result} from '../Utils/Result';
|
import {Result} from '../Utils/Result';
|
||||||
|
|
||||||
@@ -63,24 +67,41 @@ export function validateUseMemo(fn: HIRFunction): Result<void, CompilerError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (body.loweredFunc.func.params.length > 0) {
|
if (body.loweredFunc.func.params.length > 0) {
|
||||||
errors.push({
|
const firstParam = body.loweredFunc.func.params[0];
|
||||||
severity: ErrorSeverity.InvalidReact,
|
const loc =
|
||||||
reason: 'useMemo callbacks may not accept any arguments',
|
firstParam.kind === 'Identifier'
|
||||||
description: null,
|
? firstParam.loc
|
||||||
loc: body.loc,
|
: firstParam.place.loc;
|
||||||
suggestions: null,
|
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) {
|
if (body.loweredFunc.func.async || body.loweredFunc.func.generator) {
|
||||||
errors.push({
|
errors.pushDiagnostic(
|
||||||
severity: ErrorSeverity.InvalidReact,
|
CompilerDiagnostic.create({
|
||||||
reason:
|
severity: ErrorSeverity.InvalidReact,
|
||||||
'useMemo callbacks may not be async or generator functions',
|
category:
|
||||||
description: null,
|
'useMemo callbacks may not be async or generator functions',
|
||||||
loc: body.loc,
|
description:
|
||||||
suggestions: null,
|
'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;
|
break;
|
||||||
|
|||||||
@@ -36,8 +36,10 @@ function Component() {
|
|||||||
## Error
|
## Error
|
||||||
|
|
||||||
```
|
```
|
||||||
Found 2 errors:
|
Found 1 error:
|
||||||
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
|
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
|
error.bug-old-inference-false-positive-ref-validation-in-use-effect.ts:20:12
|
||||||
18 | );
|
18 | );
|
||||||
@@ -51,24 +53,19 @@ error.bug-old-inference-false-positive-ref-validation-in-use-effect.ts:20:12
|
|||||||
> 23 | }
|
> 23 | }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
> 24 | }, [update]);
|
> 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 |
|
25 |
|
||||||
26 | return 'ok';
|
26 | return 'ok';
|
||||||
27 | }
|
27 | }
|
||||||
|
|
||||||
|
|
||||||
Error: The function modifies a local variable here
|
|
||||||
|
|
||||||
error.bug-old-inference-false-positive-ref-validation-in-use-effect.ts:14:6
|
error.bug-old-inference-false-positive-ref-validation-in-use-effect.ts:14:6
|
||||||
12 | ...partialParams,
|
12 | ...partialParams,
|
||||||
13 | };
|
13 | };
|
||||||
> 14 | nextParams.param = 'value';
|
> 14 | nextParams.param = 'value';
|
||||||
| ^^^^^^^^^^ The function modifies a local variable here
|
| ^^^^^^^^^^ This modifies a local variable
|
||||||
15 | console.log(nextParams);
|
15 | console.log(nextParams);
|
||||||
16 | },
|
16 | },
|
||||||
17 | [params]
|
17 | [params]
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -29,20 +29,18 @@ export const FIXTURE_ENTRYPOINT = {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.context-variable-only-chained-assign.ts:10:19
|
||||||
8 | };
|
8 | };
|
||||||
9 | const fn2 = () => {
|
9 | const fn2 = () => {
|
||||||
> 10 | const copy2 = (x = 4);
|
> 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)];
|
11 | return [invoke(fn1), copy2, identity(copy2)];
|
||||||
12 | };
|
12 | };
|
||||||
13 | return invoke(fn2);
|
13 | return invoke(fn2);
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -18,20 +18,18 @@ function Component() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.declare-reassign-variable-in-function-declaration.ts:4:4
|
||||||
2 | let x = null;
|
2 | let x = null;
|
||||||
3 | function foo() {
|
3 | function foo() {
|
||||||
> 4 | x = 9;
|
> 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 | }
|
5 | }
|
||||||
6 | const y = bar(foo);
|
6 | const y = bar(foo);
|
||||||
7 | return <Child y={y} />;
|
7 | return <Child y={y} />;
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -16,20 +16,18 @@ function Component() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.function-expression-references-variable-its-assigned-to.ts:3:4
|
||||||
1 | function Component() {
|
1 | function Component() {
|
||||||
2 | let callback = () => {
|
2 | let callback = () => {
|
||||||
> 3 | callback = null;
|
> 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 | };
|
4 | };
|
||||||
5 | return <div onClick={callback} />;
|
5 | return <div onClick={callback} />;
|
||||||
6 | }
|
6 | }
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -18,6 +18,8 @@ function component(a, b) {
|
|||||||
Found 1 error:
|
Found 1 error:
|
||||||
Error: useMemo callbacks may not be async or generator functions
|
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
|
error.invalid-ReactUseMemo-async-callback.ts:2:24
|
||||||
1 | function component(a, b) {
|
1 | function component(a, b) {
|
||||||
> 2 | let x = React.useMemo(async () => {
|
> 2 | let x = React.useMemo(async () => {
|
||||||
@@ -25,12 +27,10 @@ error.invalid-ReactUseMemo-async-callback.ts:2:24
|
|||||||
> 3 | await a;
|
> 3 | await a;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
> 4 | }, []);
|
> 4 | }, []);
|
||||||
| ^^^^ useMemo callbacks may not be async or generator functions
|
| ^^^^ Async and generator functions are not supported
|
||||||
5 | return x;
|
5 | return x;
|
||||||
6 | }
|
6 | }
|
||||||
7 |
|
7 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -23,30 +23,30 @@ function Component({item, cond}) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 2 errors:
|
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
|
error.invalid-conditional-setState-in-useMemo.ts:7:6
|
||||||
5 | useMemo(() => {
|
5 | useMemo(() => {
|
||||||
6 | if (cond) {
|
6 | if (cond) {
|
||||||
> 7 | setPrevItem(item);
|
> 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);
|
8 | setState(0);
|
||||||
9 | }
|
9 | }
|
||||||
10 | }, [cond, key, init]);
|
10 | }, [cond, key, init]);
|
||||||
|
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: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
|
||||||
|
|
||||||
error.invalid-conditional-setState-in-useMemo.ts:8:6
|
error.invalid-conditional-setState-in-useMemo.ts:8:6
|
||||||
6 | if (cond) {
|
6 | if (cond) {
|
||||||
7 | setPrevItem(item);
|
7 | setPrevItem(item);
|
||||||
> 8 | setState(0);
|
> 8 | setState(0);
|
||||||
| ^^^^^^^^ Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
| ^^^^^^^^ Found setState() within useMemo()
|
||||||
9 | }
|
9 | }
|
||||||
10 | }, [cond, key, init]);
|
10 | }, [cond, key, init]);
|
||||||
11 |
|
11 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -17,8 +17,10 @@ function useFoo() {
|
|||||||
## Error
|
## Error
|
||||||
|
|
||||||
```
|
```
|
||||||
Found 2 errors:
|
Found 1 error:
|
||||||
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
|
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
|
error.invalid-hook-function-argument-mutates-local-variable.ts:5:10
|
||||||
3 | function useFoo() {
|
3 | function useFoo() {
|
||||||
@@ -28,23 +30,18 @@ error.invalid-hook-function-argument-mutates-local-variable.ts:5:10
|
|||||||
> 6 | cache.set('key', 'value');
|
> 6 | cache.set('key', 'value');
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
> 7 | });
|
> 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 | }
|
8 | }
|
||||||
9 |
|
9 |
|
||||||
|
|
||||||
|
|
||||||
Error: The function modifies a local variable here
|
|
||||||
|
|
||||||
error.invalid-hook-function-argument-mutates-local-variable.ts:6:4
|
error.invalid-hook-function-argument-mutates-local-variable.ts:6:4
|
||||||
4 | const cache = new Map();
|
4 | const cache = new Map();
|
||||||
5 | useHook(() => {
|
5 | useHook(() => {
|
||||||
> 6 | cache.set('key', 'value');
|
> 6 | cache.set('key', 'value');
|
||||||
| ^^^^^ The function modifies a local variable here
|
| ^^^^^ This modifies a local variable
|
||||||
7 | });
|
7 | });
|
||||||
8 | }
|
8 | }
|
||||||
9 |
|
9 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -47,20 +47,18 @@ function Component() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.invalid-nested-function-reassign-local-variable-in-effect.ts:7:6
|
||||||
5 | // Create the reassignment function inside another function, then return it
|
5 | // Create the reassignment function inside another function, then return it
|
||||||
6 | const reassignLocal = newValue => {
|
6 | const reassignLocal = newValue => {
|
||||||
> 7 | local = 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 | };
|
8 | };
|
||||||
9 | return reassignLocal;
|
9 | return reassignLocal;
|
||||||
10 | };
|
10 | };
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -17,30 +17,27 @@ function Component() {
|
|||||||
## Error
|
## Error
|
||||||
|
|
||||||
```
|
```
|
||||||
Found 2 errors:
|
Found 1 error:
|
||||||
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
|
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
|
error.invalid-pass-mutable-function-as-prop.ts:7:18
|
||||||
5 | cache.set('key', 'value');
|
5 | cache.set('key', 'value');
|
||||||
6 | };
|
6 | };
|
||||||
> 7 | return <Foo fn={fn} />;
|
> 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 | }
|
8 | }
|
||||||
9 |
|
9 |
|
||||||
|
|
||||||
|
|
||||||
Error: The function modifies a local variable here
|
|
||||||
|
|
||||||
error.invalid-pass-mutable-function-as-prop.ts:5:4
|
error.invalid-pass-mutable-function-as-prop.ts:5:4
|
||||||
3 | const cache = new Map();
|
3 | const cache = new Map();
|
||||||
4 | const fn = () => {
|
4 | const fn = () => {
|
||||||
> 5 | cache.set('key', 'value');
|
> 5 | cache.set('key', 'value');
|
||||||
| ^^^^^ The function modifies a local variable here
|
| ^^^^^ This modifies a local variable
|
||||||
6 | };
|
6 | };
|
||||||
7 | return <Foo fn={fn} />;
|
7 | return <Foo fn={fn} />;
|
||||||
8 | }
|
8 | }
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -16,20 +16,18 @@ function useFoo() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.invalid-reassign-local-in-hook-return-value.ts:4:4
|
||||||
2 | let x = 0;
|
2 | let x = 0;
|
||||||
3 | return value => {
|
3 | return value => {
|
||||||
> 4 | x = 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 | };
|
5 | };
|
||||||
6 | }
|
6 | }
|
||||||
7 |
|
7 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -48,20 +48,18 @@ function Component() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.invalid-reassign-local-variable-in-effect.ts:7:4
|
||||||
5 |
|
5 |
|
||||||
6 | const reassignLocal = newValue => {
|
6 | const reassignLocal = newValue => {
|
||||||
> 7 | local = 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 | };
|
8 | };
|
||||||
9 |
|
9 |
|
||||||
10 | const onMount = newValue => {
|
10 | const onMount = newValue => {
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -49,20 +49,18 @@ function Component() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.invalid-reassign-local-variable-in-hook-argument.ts:8:4
|
||||||
6 |
|
6 |
|
||||||
7 | const reassignLocal = newValue => {
|
7 | const reassignLocal = newValue => {
|
||||||
> 8 | local = 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 | };
|
9 | };
|
||||||
10 |
|
10 |
|
||||||
11 | const callback = newValue => {
|
11 | const callback = newValue => {
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -42,20 +42,18 @@ function Component() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.invalid-reassign-local-variable-in-jsx-callback.ts:5:4
|
||||||
3 |
|
3 |
|
||||||
4 | const reassignLocal = newValue => {
|
4 | const reassignLocal = newValue => {
|
||||||
> 5 | local = 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 | };
|
6 | };
|
||||||
7 |
|
7 |
|
||||||
8 | const onClick = newValue => {
|
8 | const onClick = newValue => {
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -19,8 +19,10 @@ function useFoo() {
|
|||||||
## Error
|
## Error
|
||||||
|
|
||||||
```
|
```
|
||||||
Found 2 errors:
|
Found 1 error:
|
||||||
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
|
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
|
error.invalid-return-mutable-function-from-hook.ts:7:9
|
||||||
5 | useHook(); // for inference to kick in
|
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');
|
> 8 | cache.set('key', 'value');
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
> 9 | };
|
> 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 | }
|
10 | }
|
||||||
11 |
|
11 |
|
||||||
|
|
||||||
|
|
||||||
Error: The function modifies a local variable here
|
|
||||||
|
|
||||||
error.invalid-return-mutable-function-from-hook.ts:8:4
|
error.invalid-return-mutable-function-from-hook.ts:8:4
|
||||||
6 | const cache = new Map();
|
6 | const cache = new Map();
|
||||||
7 | return () => {
|
7 | return () => {
|
||||||
> 8 | cache.set('key', 'value');
|
> 8 | cache.set('key', 'value');
|
||||||
| ^^^^^ The function modifies a local variable here
|
| ^^^^^ This modifies a local variable
|
||||||
9 | };
|
9 | };
|
||||||
10 | }
|
10 | }
|
||||||
11 |
|
11 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -27,18 +27,18 @@ function useKeyedState({key, init}) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.invalid-setState-in-useMemo-indirect-useCallback.ts:13:4
|
||||||
11 |
|
11 |
|
||||||
12 | useMemo(() => {
|
12 | useMemo(() => {
|
||||||
> 13 | fn();
|
> 13 | fn();
|
||||||
| ^^ Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
| ^^ Found setState() within useMemo()
|
||||||
14 | }, [key, init]);
|
14 | }, [key, init]);
|
||||||
15 |
|
15 |
|
||||||
16 | return state;
|
16 | return state;
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -21,30 +21,30 @@ function useKeyedState({key, init}) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 2 errors:
|
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
|
error.invalid-setState-in-useMemo.ts:6:4
|
||||||
4 |
|
4 |
|
||||||
5 | useMemo(() => {
|
5 | useMemo(() => {
|
||||||
> 6 | setPrevKey(key);
|
> 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);
|
7 | setState(init);
|
||||||
8 | }, [key, init]);
|
8 | }, [key, init]);
|
||||||
9 |
|
9 |
|
||||||
|
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: Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)
|
|
||||||
|
|
||||||
error.invalid-setState-in-useMemo.ts:7:4
|
error.invalid-setState-in-useMemo.ts:7:4
|
||||||
5 | useMemo(() => {
|
5 | useMemo(() => {
|
||||||
6 | setPrevKey(key);
|
6 | setPrevKey(key);
|
||||||
> 7 | setState(init);
|
> 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]);
|
8 | }, [key, init]);
|
||||||
9 |
|
9 |
|
||||||
10 | return state;
|
10 | return state;
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -47,8 +47,10 @@ hook useMemoMap<TInput: interface {}, TOutput>(
|
|||||||
## Error
|
## Error
|
||||||
|
|
||||||
```
|
```
|
||||||
Found 2 errors:
|
Found 1 error:
|
||||||
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
|
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
|
undefined:21:9
|
||||||
19 | map: TInput => TOutput
|
19 | map: TInput => TOutput
|
||||||
@@ -86,23 +88,18 @@ undefined:21:9
|
|||||||
> 36 | };
|
> 36 | };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
> 37 | }, [map]);
|
> 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 | }
|
38 | }
|
||||||
39 |
|
39 |
|
||||||
|
|
||||||
|
|
||||||
Error: The function modifies a local variable here
|
|
||||||
|
|
||||||
undefined:33:8
|
undefined:33:8
|
||||||
31 | if (output == null) {
|
31 | if (output == null) {
|
||||||
32 | output = map(input);
|
32 | output = map(input);
|
||||||
> 33 | cache.set(input, output);
|
> 33 | cache.set(input, output);
|
||||||
| ^^^^^ The function modifies a local variable here
|
| ^^^^^ This modifies a local variable
|
||||||
34 | }
|
34 | }
|
||||||
35 | return output;
|
35 | return output;
|
||||||
36 | };
|
36 | };
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -20,30 +20,30 @@ function Component(props) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 2 errors:
|
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
|
error.invalid-unconditional-set-state-in-render.ts:6:2
|
||||||
4 | const aliased = setX;
|
4 | const aliased = setX;
|
||||||
5 |
|
5 |
|
||||||
> 6 | setX(1);
|
> 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);
|
7 | aliased(2);
|
||||||
8 |
|
8 |
|
||||||
9 | return x;
|
9 | return x;
|
||||||
|
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: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)
|
|
||||||
|
|
||||||
error.invalid-unconditional-set-state-in-render.ts:7:2
|
error.invalid-unconditional-set-state-in-render.ts:7:2
|
||||||
5 |
|
5 |
|
||||||
6 | setX(1);
|
6 | setX(1);
|
||||||
> 7 | aliased(2);
|
> 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 |
|
8 |
|
||||||
9 | return x;
|
9 | return x;
|
||||||
10 | }
|
10 | }
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -18,6 +18,8 @@ function component(a, b) {
|
|||||||
Found 1 error:
|
Found 1 error:
|
||||||
Error: useMemo callbacks may not be async or generator functions
|
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
|
error.invalid-useMemo-async-callback.ts:2:18
|
||||||
1 | function component(a, b) {
|
1 | function component(a, b) {
|
||||||
> 2 | let x = useMemo(async () => {
|
> 2 | let x = useMemo(async () => {
|
||||||
@@ -25,12 +27,10 @@ error.invalid-useMemo-async-callback.ts:2:18
|
|||||||
> 3 | await a;
|
> 3 | await a;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
> 4 | }, []);
|
> 4 | }, []);
|
||||||
| ^^^^ useMemo callbacks may not be async or generator functions
|
| ^^^^ Async and generator functions are not supported
|
||||||
5 | return x;
|
5 | return x;
|
||||||
6 | }
|
6 | }
|
||||||
7 |
|
7 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -14,17 +14,17 @@ function component(a, b) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.invalid-useMemo-callback-args.ts:2:18
|
||||||
1 | function component(a, b) {
|
1 | function component(a, b) {
|
||||||
> 2 | let x = useMemo(c => a, []);
|
> 2 | let x = useMemo(c => a, []);
|
||||||
| ^^^^^^ useMemo callbacks may not accept any arguments
|
| ^
|
||||||
3 | return x;
|
3 | return x;
|
||||||
4 | }
|
4 | }
|
||||||
5 |
|
5 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -33,20 +33,18 @@ export const FIXTURE_ENTRYPOINT = {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.mutable-range-shared-inner-outer-function.ts:8:6
|
||||||
6 | const f = () => {
|
6 | const f = () => {
|
||||||
7 | if (cond) {
|
7 | if (cond) {
|
||||||
> 8 | a = {};
|
> 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 = [];
|
9 | b = [];
|
||||||
10 | } else {
|
10 | } else {
|
||||||
11 | a = {};
|
11 | a = {};
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -18,20 +18,18 @@ function Component() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.todo-function-expression-references-later-variable-declaration.ts:3:4
|
||||||
1 | function Component() {
|
1 | function Component() {
|
||||||
2 | let callback = () => {
|
2 | let callback = () => {
|
||||||
> 3 | onClick = () => {};
|
> 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 | };
|
4 | };
|
||||||
5 | let onClick;
|
5 | let onClick;
|
||||||
6 |
|
6 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -23,18 +23,18 @@ function Component(props) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.unconditional-set-state-in-render-after-loop-break.ts:11:2
|
||||||
9 | }
|
9 | }
|
||||||
10 | }
|
10 | }
|
||||||
> 11 | setState(true);
|
> 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;
|
12 | return state;
|
||||||
13 | }
|
13 | }
|
||||||
14 |
|
14 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -18,18 +18,18 @@ function Component(props) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.unconditional-set-state-in-render-after-loop.ts:6:2
|
||||||
4 | for (const _ of props) {
|
4 | for (const _ of props) {
|
||||||
5 | }
|
5 | }
|
||||||
> 6 | setState(true);
|
> 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;
|
7 | return state;
|
||||||
8 | }
|
8 | }
|
||||||
9 |
|
9 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -23,18 +23,18 @@ function Component(props) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.unconditional-set-state-in-render-with-loop-throw.ts:11:2
|
||||||
9 | }
|
9 | }
|
||||||
10 | }
|
10 | }
|
||||||
> 11 | setState(true);
|
> 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;
|
12 | return state;
|
||||||
13 | }
|
13 | }
|
||||||
14 |
|
14 |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -21,18 +21,18 @@ function Component(props) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.unconditional-set-state-lambda.ts:8:2
|
||||||
6 | setX(1);
|
6 | setX(1);
|
||||||
7 | };
|
7 | };
|
||||||
> 8 | foo();
|
> 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 |
|
9 |
|
||||||
10 | return [x];
|
10 | return [x];
|
||||||
11 | }
|
11 | }
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -29,18 +29,18 @@ function Component(props) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
Found 1 error:
|
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
|
error.unconditional-set-state-nested-function-expressions.ts:16:2
|
||||||
14 | bar();
|
14 | bar();
|
||||||
15 | };
|
15 | };
|
||||||
> 16 | baz();
|
> 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 |
|
17 |
|
||||||
18 | return [x];
|
18 | return [x];
|
||||||
19 | }
|
19 | }
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ function Component(props) {
|
|||||||
## Logs
|
## 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}
|
{"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
|
## 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}
|
{"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
|
## 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}
|
{"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
|
## 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}
|
{"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:
|
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
|
error.invalid-reassign-local-variable-in-jsx-callback.ts:6:4
|
||||||
4 |
|
4 |
|
||||||
5 | const reassignLocal = newValue => {
|
5 | const reassignLocal = newValue => {
|
||||||
> 6 | local = 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 | };
|
7 | };
|
||||||
8 |
|
8 |
|
||||||
9 | const onClick = newValue => {
|
9 | const onClick = newValue => {
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user