@samitouri / QOS-React-1 / commits / fe04dbcbc4

[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 +};