Skip to content

Commit 4df098c

Browse files
authored
[compiler] Don't include useEffectEvent values in autodeps (#33450)
Summary: useEffectEvent values are not meant to be added to the dep array
1 parent 95bcf87 commit 4df098c

File tree

6 files changed

+109
-1
lines changed

6 files changed

+109
-1
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
BuiltInSetId,
1818
BuiltInUseActionStateId,
1919
BuiltInUseContextHookId,
20+
BuiltInUseEffectEventId,
2021
BuiltInUseEffectHookId,
2122
BuiltInUseInsertionEffectHookId,
2223
BuiltInUseLayoutEffectHookId,
@@ -27,6 +28,7 @@ import {
2728
BuiltInUseTransitionId,
2829
BuiltInWeakMapId,
2930
BuiltInWeakSetId,
31+
BuiltinEffectEventId,
3032
ReanimatedSharedValueId,
3133
ShapeRegistry,
3234
addFunction,
@@ -722,6 +724,27 @@ const REACT_APIS: Array<[string, BuiltInType]> = [
722724
BuiltInFireId,
723725
),
724726
],
727+
[
728+
'useEffectEvent',
729+
addHook(
730+
DEFAULT_SHAPES,
731+
{
732+
positionalParams: [],
733+
restParam: Effect.Freeze,
734+
returnType: {
735+
kind: 'Function',
736+
return: {kind: 'Poly'},
737+
shapeId: BuiltinEffectEventId,
738+
isConstructor: false,
739+
},
740+
calleeEffect: Effect.Read,
741+
hookKind: 'useEffectEvent',
742+
// Frozen because it should not mutate any locally-bound values
743+
returnValueKind: ValueKind.Frozen,
744+
},
745+
BuiltInUseEffectEventId,
746+
),
747+
],
725748
];
726749

727750
TYPED_GLOBALS.push(

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,13 @@ export function isFireFunctionType(id: Identifier): boolean {
17851785
);
17861786
}
17871787

1788+
export function isEffectEventFunctionType(id: Identifier): boolean {
1789+
return (
1790+
id.type.kind === 'Function' &&
1791+
id.type.shapeId === 'BuiltInEffectEventFunction'
1792+
);
1793+
}
1794+
17881795
export function isStableType(id: Identifier): boolean {
17891796
return (
17901797
isSetStateType(id) ||

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export type HookKind =
131131
| 'useCallback'
132132
| 'useTransition'
133133
| 'useImperativeHandle'
134+
| 'useEffectEvent'
134135
| 'Custom';
135136

136137
/*
@@ -226,6 +227,8 @@ export const BuiltInUseTransitionId = 'BuiltInUseTransition';
226227
export const BuiltInStartTransitionId = 'BuiltInStartTransition';
227228
export const BuiltInFireId = 'BuiltInFire';
228229
export const BuiltInFireFunctionId = 'BuiltInFireFunction';
230+
export const BuiltInUseEffectEventId = 'BuiltInUseEffectEvent';
231+
export const BuiltinEffectEventId = 'BuiltInEffectEventFunction';
229232

230233
// See getReanimatedModuleType() in Globals.ts — this is part of supporting Reanimated's ref-like types
231234
export const ReanimatedSharedValueId = 'ReanimatedSharedValueId';
@@ -948,6 +951,19 @@ addObject(BUILTIN_SHAPES, BuiltInRefValueId, [
948951
['*', {kind: 'Object', shapeId: BuiltInRefValueId}],
949952
]);
950953

954+
addFunction(
955+
BUILTIN_SHAPES,
956+
[],
957+
{
958+
positionalParams: [],
959+
restParam: Effect.ConditionallyMutate,
960+
returnType: {kind: 'Poly'},
961+
calleeEffect: Effect.ConditionallyMutate,
962+
returnValueKind: ValueKind.Mutable,
963+
},
964+
BuiltinEffectEventId,
965+
);
966+
951967
/**
952968
* MixedReadOnly =
953969
* | primitive

compiler/packages/babel-plugin-react-compiler/src/Inference/InferEffectDependencies.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
HIR,
3232
BasicBlock,
3333
BlockId,
34+
isEffectEventFunctionType,
3435
} from '../HIR';
3536
import {collectHoistablePropertyLoadsInInnerFn} from '../HIR/CollectHoistablePropertyLoads';
3637
import {collectOptionalChainSidemap} from '../HIR/CollectOptionalChainDependencies';
@@ -209,7 +210,8 @@ export function inferEffectDependencies(fn: HIRFunction): void {
209210
((isUseRefType(maybeDep.identifier) ||
210211
isSetStateType(maybeDep.identifier)) &&
211212
!reactiveIds.has(maybeDep.identifier.id)) ||
212-
isFireFunctionType(maybeDep.identifier)
213+
isFireFunctionType(maybeDep.identifier) ||
214+
isEffectEventFunctionType(maybeDep.identifier)
213215
) {
214216
// exclude non-reactive hook results, which will never be in a memo block
215217
continue;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @inferEffectDependencies
6+
import {useEffect, useEffectEvent} from 'react';
7+
import {print} from 'shared-runtime';
8+
9+
/**
10+
* We do not include effect events in dep arrays.
11+
*/
12+
function NonReactiveEffectEvent() {
13+
const fn = useEffectEvent(() => print('hello world'));
14+
useEffect(() => fn());
15+
}
16+
17+
```
18+
19+
## Code
20+
21+
```javascript
22+
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
23+
import { useEffect, useEffectEvent } from "react";
24+
import { print } from "shared-runtime";
25+
26+
/**
27+
* We do not include effect events in dep arrays.
28+
*/
29+
function NonReactiveEffectEvent() {
30+
const $ = _c(2);
31+
const fn = useEffectEvent(_temp);
32+
let t0;
33+
if ($[0] !== fn) {
34+
t0 = () => fn();
35+
$[0] = fn;
36+
$[1] = t0;
37+
} else {
38+
t0 = $[1];
39+
}
40+
useEffect(t0, []);
41+
}
42+
function _temp() {
43+
return print("hello world");
44+
}
45+
46+
```
47+
48+
### Eval output
49+
(kind: exception) Fixture not implemented
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @inferEffectDependencies
2+
import {useEffect, useEffectEvent} from 'react';
3+
import {print} from 'shared-runtime';
4+
5+
/**
6+
* We do not include effect events in dep arrays.
7+
*/
8+
function NonReactiveEffectEvent() {
9+
const fn = useEffectEvent(() => print('hello world'));
10+
useEffect(() => fn());
11+
}

0 commit comments

Comments
 (0)