[compiler] Fix to ref access check to ban ref?.current
ghstack-source-id: ea417a468eac2607ce8d1dddcb2e9581e1c4db27 Pull Request resolved: https://github.com/facebook/react/pull/31360
Mike Vitousek committed
Oct 25, 2024 at 16:47 UTC
fe04dbcbc4185d7c9d7afebbe18589d2b681a88c
3 files changed
+58
-7
compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts
+15
-7
@@ -214,16 +214,24 @@ function joinRefAccessTypes(...types: Array<RefAccessType>): RefAccessType {
214
return b;
215
} else if (b.kind === 'None') {
216
return a;
217
- } else if (a.kind === 'Guard' || b.kind === 'Guard') {
218
- if (a.kind === 'Guard' && b.kind === 'Guard' && a.refId === b.refId) {
217
+ } else if (a.kind === 'Guard') {
218
+ if (b.kind === 'Guard' && a.refId === b.refId) {
219
return a;
220
+ } else if (b.kind === 'Nullable' || b.kind === 'Guard') {
221
+ return {kind: 'None'};
222
+ } else {
223
+ return b;
224
}
221
- return {kind: 'None'};
222
- } else if (a.kind === 'Nullable' || b.kind === 'Nullable') {
223
- if (a.kind === 'Nullable' && b.kind === 'Nullable') {
224
- return a;
225
+ } else if (b.kind === 'Guard') {
226
+ if (a.kind === 'Nullable') {
227
+ return {kind: 'None'};
228
+ } else {
229
+ return b;
230
}
226
- return {kind: 'None'};
231
+ } else if (a.kind === 'Nullable') {
232
+ return b;
233
+ } else if (b.kind === 'Nullable') {
234
+ return a;
235
} else {
236
return joinRefAccessRefTypes(a, b);
237
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-optional.expect.md
new
+32
@@ -0,0 +1,32 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+import {useRef} from 'react';
6
+
7
+function Component(props) {
8
+ const ref = useRef();
9
+ return ref?.current;
10
+}
11
+
12
+export const FIXTURE_ENTRYPOINT = {
13
+ fn: Component,
14
+ params: [],
15
+};
16
+
17
+```
18
+
19
+
20
+## Error
21
+
22
+```
23
+ 3 | function Component(props) {
24
+ 4 | const ref = useRef();
25
+> 5 | return ref?.current;
26
+ | ^^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef) (5:5)
27
+ 6 | }
28
+ 7 |
29
+ 8 | export const FIXTURE_ENTRYPOINT = {
30
+```
31
+
32
+
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-optional.js
new
+11
@@ -0,0 +1,11 @@
1
+import {useRef} from 'react';
2
+
3
+function Component(props) {
4
+ const ref = useRef();
5
+ return ref?.current;
6
+}
7
+
8
+export const FIXTURE_ENTRYPOINT = {
9
+ fn: Component,
10
+ params: [],
11
+};