Skip to content

Commit 0e1d7ad

Browse files
committed
Support experimental_use hook prefixes
Summary: We often use `experimental_use` as a prefix for experimental hooks. We should treat these values as hooks by the compiler so that we don't [accidentally compile those calls](https://0xeac7-forget.vercel.app/#N4Igzg9grgTgxgUxALhASwLYAcIwC4AEwBCAHlgjJggHZ4CGANgPpRgICiAZlwnHhwButPABoCbBACUEXAgF8CXGBAwEA5DAT1+6gNwAdGkbI58BACaz6URoS5Qa-NBBoEAsgE8AgliwAKYCwVLHkASiIjAgI4VzBCLTkAXgl2GS5-MMM3AgB6XIIAVSdVDBElXBIYFRgovILTSmo6JlZ2bl5+IRF-TIIkgD4iAkSAOjhYLTp+ghpbRj0FMLrYmniCUhnGqjKWlkkOvgFhOl6IweHVyEYEUcYIAHN-YIgsCPDs6IOeI7P+odImSydS0eFgbgAPBY0IIBgAJBCMe4EADquEYFghuWhsOy8iMIHkQA) or report ref.current access errors in them. --
1 parent 4448b18 commit 0e1d7ad

File tree

5 files changed

+169
-1
lines changed

5 files changed

+169
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1058,8 +1058,9 @@ export class Environment {
10581058
const REANIMATED_MODULE_NAME = 'react-native-reanimated';
10591059

10601060
// From https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js#LL18C1-L23C2
1061+
// Augmented to support the `experimental_use` prefix we use for experimental features.
10611062
export function isHookName(name: string): boolean {
1062-
return /^use[A-Z0-9]/.test(name);
1063+
return /^(experimental_)?use[A-Z0-9]/.test(name);
10631064
}
10641065

10651066
export function parseEnvironmentConfig(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @flow
6+
7+
import {experimental_useEffectEvent, useEffect} from 'react';
8+
9+
component Component(prop: number) {
10+
const x = experimental_useEffectEvent(() => {
11+
console.log(prop);
12+
});
13+
useEffect(() => x());
14+
return prop;
15+
}
16+
17+
export const FIXTURE_ENTRYPOINT = {
18+
fn: Component,
19+
params: [{prop: 1}],
20+
};
21+
22+
```
23+
24+
## Code
25+
26+
```javascript
27+
import { c as _c } from "react/compiler-runtime";
28+
29+
import { experimental_useEffectEvent, useEffect } from "react";
30+
31+
function Component(t0) {
32+
const $ = _c(4);
33+
const { prop } = t0;
34+
let t1;
35+
if ($[0] !== prop) {
36+
t1 = () => {
37+
console.log(prop);
38+
};
39+
$[0] = prop;
40+
$[1] = t1;
41+
} else {
42+
t1 = $[1];
43+
}
44+
const x = experimental_useEffectEvent(t1);
45+
let t2;
46+
if ($[2] !== x) {
47+
t2 = () => x();
48+
$[2] = x;
49+
$[3] = t2;
50+
} else {
51+
t2 = $[3];
52+
}
53+
useEffect(t2);
54+
return prop;
55+
}
56+
57+
export const FIXTURE_ENTRYPOINT = {
58+
fn: Component,
59+
params: [{ prop: 1 }],
60+
};
61+
62+
```
63+
64+
### Eval output
65+
(kind: ok) 1
66+
logs: [1]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// @flow
2+
3+
import {experimental_useEffectEvent, useEffect} from 'react';
4+
5+
component Component(prop: number) {
6+
const x = experimental_useEffectEvent(() => {
7+
console.log(prop);
8+
});
9+
useEffect(() => x());
10+
return prop;
11+
}
12+
13+
export const FIXTURE_ENTRYPOINT = {
14+
fn: Component,
15+
params: [{prop: 1}],
16+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @flow
6+
7+
import {experimental_useEffectEvent, useRef} from 'react';
8+
9+
component Component(prop: number) {
10+
const ref1 = useRef(null);
11+
const ref2 = useRef(1);
12+
experimental_useEffectEvent(ref1, () => {
13+
const precomputed = prop + ref2.current;
14+
return {
15+
foo: () => prop + ref2.current + precomputed,
16+
};
17+
}, [prop]);
18+
}
19+
20+
export const FIXTURE_ENTRYPOINT = {
21+
fn: Component,
22+
params: [{prop: 1}],
23+
};
24+
25+
```
26+
27+
## Code
28+
29+
```javascript
30+
import { c as _c } from "react/compiler-runtime";
31+
32+
import { experimental_useEffectEvent, useRef } from "react";
33+
34+
function Component(t0) {
35+
const $ = _c(3);
36+
const { prop } = t0;
37+
const ref1 = useRef(null);
38+
const ref2 = useRef(1);
39+
let t1;
40+
let t2;
41+
if ($[0] !== prop) {
42+
t1 = () => {
43+
const precomputed = prop + ref2.current;
44+
return { foo: () => prop + ref2.current + precomputed };
45+
};
46+
47+
t2 = [prop];
48+
$[0] = prop;
49+
$[1] = t1;
50+
$[2] = t2;
51+
} else {
52+
t1 = $[1];
53+
t2 = $[2];
54+
}
55+
experimental_useEffectEvent(ref1, t1, t2);
56+
}
57+
58+
export const FIXTURE_ENTRYPOINT = {
59+
fn: Component,
60+
params: [{ prop: 1 }],
61+
};
62+
63+
```
64+
65+
### Eval output
66+
(kind: ok)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// @flow
2+
3+
import {experimental_useEffectEvent, useRef} from 'react';
4+
5+
component Component(prop: number) {
6+
const ref1 = useRef(null);
7+
const ref2 = useRef(1);
8+
experimental_useEffectEvent(ref1, () => {
9+
const precomputed = prop + ref2.current;
10+
return {
11+
foo: () => prop + ref2.current + precomputed,
12+
};
13+
}, [prop]);
14+
}
15+
16+
export const FIXTURE_ENTRYPOINT = {
17+
fn: Component,
18+
params: [{prop: 1}],
19+
};

0 commit comments

Comments
 (0)