Skip to content

Commit 669a24e

Browse files
committed
[compiler] Type ref prop as a ref
ghstack-source-id: a0c061e Pull Request resolved: #29834
1 parent a532d91 commit 669a24e

File tree

7 files changed

+75
-1
lines changed

7 files changed

+75
-1
lines changed

compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ export type ObjectShape = {
188188
* the inferred types for [] and {}.
189189
*/
190190
export type ShapeRegistry = Map<string, ObjectShape>;
191+
export const BuiltInPropsId = "BuiltInProps";
191192
export const BuiltInArrayId = "BuiltInArray";
192193
export const BuiltInFunctionId = "BuiltInFunction";
193194
export const BuiltInJsxId = "BuiltInJsx";
@@ -207,6 +208,11 @@ export const BuiltInDispatchId = "BuiltInDispatch";
207208
// ShapeRegistry with default definitions for built-ins.
208209
export const BUILTIN_SHAPES: ShapeRegistry = new Map();
209210

211+
// If the `ref` prop exists, it has the ref type
212+
addObject(BUILTIN_SHAPES, BuiltInPropsId, [
213+
["ref", { kind: "Object", shapeId: BuiltInUseRefId }],
214+
]);
215+
210216
/* Built-in array shape */
211217
addObject(BUILTIN_SHAPES, BuiltInArrayId, [
212218
[

compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export function printFunction(fn: HIRFunction): string {
6161
.join(", ") +
6262
")";
6363
}
64+
definition += ` type=${fn.fnType}`;
6465
if (definition.length !== 0) {
6566
output.push(definition);
6667
}

compiler/packages/babel-plugin-react-compiler/src/TypeInference/InferTypes.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
BuiltInFunctionId,
2424
BuiltInJsxId,
2525
BuiltInObjectId,
26+
BuiltInPropsId,
2627
BuiltInUseRefId,
2728
} from "../HIR/ObjectShape";
2829
import { eachInstructionLValue, eachInstructionOperand } from "../HIR/visitors";
@@ -101,7 +102,13 @@ function* generate(
101102
func: HIRFunction
102103
): Generator<TypeEquation, void, undefined> {
103104
if (func.env.fnType === "Component") {
104-
const [_, ref] = func.params;
105+
const [props, ref] = func.params;
106+
if (props && props.kind === "Identifier") {
107+
yield equation(props.identifier.type, {
108+
kind: "Object",
109+
shapeId: BuiltInPropsId,
110+
});
111+
}
105112
if (ref && ref.kind === "Identifier") {
106113
yield equation(ref.identifier.type, {
107114
kind: "Object",
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @validateRefAccessDuringRender @compilationMode(infer)
6+
function Component({ ref }) {
7+
const value = ref.current;
8+
return <div>{value}</div>;
9+
}
10+
11+
```
12+
13+
14+
## Error
15+
16+
```
17+
2 | function Component({ ref }) {
18+
3 | const value = ref.current;
19+
> 4 | return <div>{value}</div>;
20+
| ^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at read $17:TObject<BuiltInRefValue> (4:4)
21+
5 | }
22+
6 |
23+
```
24+
25+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// @validateRefAccessDuringRender @compilationMode(infer)
2+
function Component({ ref }) {
3+
const value = ref.current;
4+
return <div>{value}</div>;
5+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @validateRefAccessDuringRender @compilationMode(infer)
6+
function Component(props) {
7+
const value = props.ref.current;
8+
return <div>{value}</div>;
9+
}
10+
11+
```
12+
13+
14+
## Error
15+
16+
```
17+
2 | function Component(props) {
18+
3 | const value = props.ref.current;
19+
> 4 | return <div>{value}</div>;
20+
| ^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at read $15:TObject<BuiltInRefValue> (4:4)
21+
5 | }
22+
6 |
23+
```
24+
25+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// @validateRefAccessDuringRender @compilationMode(infer)
2+
function Component(props) {
3+
const value = props.ref.current;
4+
return <div>{value}</div>;
5+
}

0 commit comments

Comments
 (0)