mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Fix using context variable as JSX element tag
Updates the lowering for JSX element tag names to check if the identifier is a context or local variable and use the appropriate instruction kind.
This commit is contained in:
@@ -2916,8 +2916,9 @@ function lowerJsxElementName(
|
||||
if (exprPath.isJSXIdentifier()) {
|
||||
const tag: string = exprPath.node.name;
|
||||
if (tag.match(/^[A-Z]/)) {
|
||||
const kind = getLoadKind(builder, exprPath);
|
||||
return lowerValueToTemporary(builder, {
|
||||
kind: "LoadLocal",
|
||||
kind: kind,
|
||||
place: lowerIdentifier(builder, exprPath),
|
||||
loc: exprLoc,
|
||||
});
|
||||
@@ -3245,7 +3246,7 @@ function getStoreKind(
|
||||
|
||||
function getLoadKind(
|
||||
builder: HIRBuilder,
|
||||
identifier: NodePath<t.Identifier>
|
||||
identifier: NodePath<t.Identifier | t.JSXIdentifier>
|
||||
): "LoadLocal" | "LoadContext" {
|
||||
const isContext = builder.isContextIdentifier(identifier);
|
||||
return isContext ? "LoadContext" : "LoadLocal";
|
||||
|
||||
@@ -267,7 +267,7 @@ export default class HIRBuilder {
|
||||
return resolvedBinding;
|
||||
}
|
||||
|
||||
isContextIdentifier(path: NodePath<t.Identifier>): boolean {
|
||||
isContextIdentifier(path: NodePath<t.Identifier | t.JSXIdentifier>): boolean {
|
||||
const binding = this.#resolveBabelBinding(path);
|
||||
if (binding) {
|
||||
return this.#env.isContextIdentifier(binding.identifier);
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import { useMemo } from "react";
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
let Component = Stringify;
|
||||
|
||||
Component = useMemo(() => {
|
||||
return Component;
|
||||
});
|
||||
|
||||
return <Component {...props} />;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ name: "Sathya" }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { useMemo, unstable_useMemoCache as useMemoCache } from "react";
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(3);
|
||||
let Component;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
Component = Stringify;
|
||||
|
||||
Component;
|
||||
let t0;
|
||||
t0 = Component;
|
||||
Component = t0;
|
||||
$[0] = Component;
|
||||
} else {
|
||||
Component = $[0];
|
||||
}
|
||||
let t0;
|
||||
if ($[1] !== props) {
|
||||
t0 = <Component {...props} />;
|
||||
$[1] = props;
|
||||
$[2] = t0;
|
||||
} else {
|
||||
t0 = $[2];
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ name: "Sathya" }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### Eval output
|
||||
(kind: ok) <div>{"name":"Sathya"}</div>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { useMemo } from "react";
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Component(props) {
|
||||
let Component = Stringify;
|
||||
|
||||
Component = useMemo(() => {
|
||||
return Component;
|
||||
});
|
||||
|
||||
return <Component {...props} />;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ name: "Sathya" }],
|
||||
};
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
let Component = Foo;
|
||||
|
||||
Component = useMemo(() => {
|
||||
return Component;
|
||||
});
|
||||
|
||||
return <Component />;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error
|
||||
|
||||
```
|
||||
6 | });
|
||||
7 |
|
||||
> 8 | return <Component />;
|
||||
| ^^^^^^^^^ [ReactForget] Invariant: Expected all references to a variable to be consistently local or context references. Identifier <unknown> Component$2 is referenced as a local variable, but was previously referenced as a context variable (8:8)
|
||||
9 | }
|
||||
10 |
|
||||
```
|
||||
|
||||
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
function Component(props) {
|
||||
let Component = Foo;
|
||||
|
||||
Component = useMemo(() => {
|
||||
return Component;
|
||||
});
|
||||
|
||||
return <Component />;
|
||||
}
|
||||
Reference in New Issue
Block a user