Skip to content

Commit e72d425

Browse files
committed
DevTools: support useEffectEvent and forward-fix experimental prefix support
1 parent 1185f88 commit e72d425

File tree

4 files changed

+118
-1
lines changed

4 files changed

+118
-1
lines changed

packages/react-debug-tools/src/ReactDebugHooks.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ function getPrimitiveStackCache(): Map<string, Array<any>> {
127127
}
128128

129129
Dispatcher.useId();
130+
131+
Dispatcher.useResourceEffect(() => ({}), []);
132+
Dispatcher.useEffectEvent(() => {});
130133
} finally {
131134
readHookLog = hookLog;
132135
hookLog = [];
@@ -749,6 +752,18 @@ function useResourceEffect(
749752
});
750753
}
751754

755+
function useEffectEvent(callback: () => mixed) {
756+
nextHook();
757+
hookLog.push({
758+
displayName: null,
759+
primitive: 'EffectEvent',
760+
stackError: new Error(),
761+
value: callback,
762+
debugInfo: null,
763+
dispatcherHookName: 'EffectEvent',
764+
});
765+
}
766+
752767
const Dispatcher: DispatcherType = {
753768
use,
754769
readContext,
@@ -773,6 +788,7 @@ const Dispatcher: DispatcherType = {
773788
useFormState,
774789
useActionState,
775790
useHostTransitionStatus,
791+
useEffectEvent,
776792
useResourceEffect,
777793
};
778794

@@ -962,7 +978,7 @@ function parseHookName(functionName: void | string): string {
962978
startIndex += 'unstable_'.length;
963979
}
964980

965-
if (functionName.slice(startIndex).startsWith('unstable_')) {
981+
if (functionName.slice(startIndex).startsWith('experimental_')) {
966982
startIndex += 'experimental_'.length;
967983
}
968984

packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2713,4 +2713,71 @@ describe('ReactHooksInspectionIntegration', () => {
27132713
]
27142714
`);
27152715
});
2716+
2717+
// @gate enableUseEffectEventHook
2718+
it('should support useEffectEvent hook', async () => {
2719+
function Foo() {
2720+
// eslint-disable-next-line no-unused-vars
2721+
const [state, myState] = React.useState();
2722+
React.experimental_useEffectEvent(function effect() {});
2723+
React.useMemo(() => 'memo', []);
2724+
2725+
return null;
2726+
}
2727+
2728+
let renderer;
2729+
await act(() => {
2730+
renderer = ReactTestRenderer.create(<Foo />, {
2731+
unstable_isConcurrent: true,
2732+
});
2733+
});
2734+
const childFiber = renderer.root.findByType(Foo)._currentFiber();
2735+
const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
2736+
expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(`
2737+
[
2738+
{
2739+
"debugInfo": null,
2740+
"hookSource": {
2741+
"columnNumber": 0,
2742+
"fileName": "**",
2743+
"functionName": "Foo",
2744+
"lineNumber": 0,
2745+
},
2746+
"id": 0,
2747+
"isStateEditable": true,
2748+
"name": "State",
2749+
"subHooks": [],
2750+
"value": undefined,
2751+
},
2752+
{
2753+
"debugInfo": null,
2754+
"hookSource": {
2755+
"columnNumber": 0,
2756+
"fileName": "**",
2757+
"functionName": "Foo",
2758+
"lineNumber": 0,
2759+
},
2760+
"id": 1,
2761+
"isStateEditable": false,
2762+
"name": "EffectEvent",
2763+
"subHooks": [],
2764+
"value": [Function],
2765+
},
2766+
{
2767+
"debugInfo": null,
2768+
"hookSource": {
2769+
"columnNumber": 0,
2770+
"fileName": "**",
2771+
"functionName": "Foo",
2772+
"lineNumber": 0,
2773+
},
2774+
"id": 2,
2775+
"isStateEditable": false,
2776+
"name": "Memo",
2777+
"subHooks": [],
2778+
"value": "memo",
2779+
},
2780+
]
2781+
`);
2782+
});
27162783
});

packages/react-devtools-shell/src/app/InspectableElements/InspectableElements.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import NestedProps from './NestedProps';
1919
import SimpleValues from './SimpleValues';
2020
import SymbolKeys from './SymbolKeys';
2121
import UseMemoCache from './UseMemoCache';
22+
import UseEffectEvent from './UseEffectEvent';
2223

2324
// TODO Add Immutable JS example
2425

@@ -36,6 +37,7 @@ export default function InspectableElements(): React.Node {
3637
<CircularReferences />
3738
<SymbolKeys />
3839
<UseMemoCache />
40+
<UseEffectEvent />
3941
</Fragment>
4042
);
4143
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import * as React from 'react';
2+
3+
const {experimental_useEffectEvent, useState, useEffect} = React;
4+
5+
export default function UseEffectEvent(): React.Node {
6+
return (
7+
<>
8+
<SingleHookCase />
9+
<HookTreeCase />
10+
</>
11+
);
12+
}
13+
14+
function SingleHookCase() {
15+
experimental_useEffectEvent(() => {});
16+
17+
return null;
18+
}
19+
20+
function useCustomHook() {
21+
const [state, setState] = useState();
22+
experimental_useEffectEvent(() => {});
23+
useEffect(() => {});
24+
25+
return [state, setState];
26+
}
27+
28+
function HookTreeCase() {
29+
useCustomHook();
30+
31+
return null;
32+
}

0 commit comments

Comments
 (0)