Skip to content

Commit

Permalink
[compiler] Support for useTransition
Browse files Browse the repository at this point in the history
Summary:
UseTransition is a builtin hook that returns a stable value, like useState. This PR represents that in Forget, and marks the startTransition function as stable.

ghstack-source-id: 0e76a64f2d0c86a4eb55c620922b4698250bb5c3
Pull Request resolved: #30681
  • Loading branch information
mvitousek committed Aug 14, 2024
1 parent 179197a commit dd8e0ba
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 1 deletion.
12 changes: 12 additions & 0 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/Globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
BuiltInUseReducerId,
BuiltInUseRefId,
BuiltInUseStateId,
BuiltInUseTransitionId,
ShapeRegistry,
addFunction,
addHook,
Expand Down Expand Up @@ -425,6 +426,17 @@ const REACT_APIS: Array<[string, BuiltInType]> = [
BuiltInUseInsertionEffectHookId,
),
],
[
'useTransition',
addHook(DEFAULT_SHAPES, {
positionalParams: [],
restParam: null,
returnType: {kind: 'Object', shapeId: BuiltInUseTransitionId},
calleeEffect: Effect.Read,
hookKind: 'useTransition',
returnValueKind: ValueKind.Frozen,
}),
],
[
'use',
addFunction(
Expand Down
9 changes: 8 additions & 1 deletion compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1601,6 +1601,12 @@ export function isUseActionStateType(id: Identifier): boolean {
);
}

export function isStartTransitionType(id: Identifier): boolean {
return (
id.type.kind === 'Function' && id.type.shapeId === 'BuiltInStartTransition'
);
}

export function isSetActionStateType(id: Identifier): boolean {
return (
id.type.kind === 'Function' && id.type.shapeId === 'BuiltInSetActionState'
Expand All @@ -1620,7 +1626,8 @@ export function isStableType(id: Identifier): boolean {
isSetStateType(id) ||
isSetActionStateType(id) ||
isDispatcherType(id) ||
isUseRefType(id)
isUseRefType(id) ||
isStartTransitionType(id)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export type HookKind =
| 'useInsertionEffect'
| 'useMemo'
| 'useCallback'
| 'useTransition'
| 'Custom';

/*
Expand Down Expand Up @@ -209,6 +210,8 @@ export const BuiltInUseOperatorId = 'BuiltInUseOperator';
export const BuiltInUseReducerId = 'BuiltInUseReducer';
export const BuiltInDispatchId = 'BuiltInDispatch';
export const BuiltInUseContextHookId = 'BuiltInUseContextHook';
export const BuiltInUseTransitionId = 'BuiltInUseTransition';
export const BuiltInStartTransitionId = 'BuiltInStartTransition';

// ShapeRegistry with default definitions for built-ins.
export const BUILTIN_SHAPES: ShapeRegistry = new Map();
Expand Down Expand Up @@ -444,6 +447,25 @@ addObject(BUILTIN_SHAPES, BuiltInUseStateId, [
],
]);

addObject(BUILTIN_SHAPES, BuiltInUseTransitionId, [
['0', {kind: 'Primitive'}],
[
'1',
addFunction(
BUILTIN_SHAPES,
[],
{
positionalParams: [],
restParam: null,
returnType: PRIMITIVE_TYPE,
calleeEffect: Effect.Read,
returnValueKind: ValueKind.Primitive,
},
BuiltInStartTransitionId,
),
],
]);

addObject(BUILTIN_SHAPES, BuiltInUseActionStateId, [
['0', {kind: 'Poly'}],
[
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

## Input

```javascript
// @validatePreserveExistingMemoizationGuarantees
import {useCallback, useTransition} from 'react';

function useFoo() {
const [t, start] = useTransition();

return useCallback(() => {
start();
}, []);
}

export const FIXTURE_ENTRYPOINT = {
fn: useFoo,
params: [],
};

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees
import { useCallback, useTransition } from "react";

function useFoo() {
const $ = _c(1);
const [t, start] = useTransition();
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = () => {
start();
};
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
}

export const FIXTURE_ENTRYPOINT = {
fn: useFoo,
params: [],
};

```
### Eval output
(kind: ok) "[[ function params=0 ]]"
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// @validatePreserveExistingMemoizationGuarantees
import {useCallback, useTransition} from 'react';

function useFoo() {
const [t, start] = useTransition();

return useCallback(() => {
start();
}, []);
}

export const FIXTURE_ENTRYPOINT = {
fn: useFoo,
params: [],
};

0 comments on commit dd8e0ba

Please sign in to comment.