DevTools: support useEffectEvent and forward-fix experimental prefix support (#32106)

- Adds support for `experimental_useEffectEvent`, now DevTools will be
able to display this hook for inspected element
- Added a use case to DevTools shell, couldn't add case, because we are
using ReactTestRenderer, which has the corresponding flag disabled.
- Forward-fix logic for handling `experimental` prefix that was added in
https://github.com/facebook/react/pull/32088.

![Screenshot 2025-01-16 at 21 24
12](https://github.com/user-attachments/assets/6fb8ff2a-be47-47b5-bbfc-73d3a586657c)
This commit is contained in:
Ruslan Lesiutin
2025-01-22 14:15:48 +00:00
committed by GitHub
parent 028c8e6cf5
commit b000019578
3 changed files with 57 additions and 1 deletions

View File

@@ -127,6 +127,13 @@ function getPrimitiveStackCache(): Map<string, Array<any>> {
}
Dispatcher.useId();
if (typeof Dispatcher.useResourceEffect === 'function') {
Dispatcher.useResourceEffect(() => ({}), []);
}
if (typeof Dispatcher.useEffectEvent === 'function') {
Dispatcher.useEffectEvent((args: empty) => {});
}
} finally {
readHookLog = hookLog;
hookLog = [];
@@ -749,6 +756,20 @@ function useResourceEffect(
});
}
function useEffectEvent<Args, F: (...Array<Args>) => mixed>(callback: F): F {
nextHook();
hookLog.push({
displayName: null,
primitive: 'EffectEvent',
stackError: new Error(),
value: callback,
debugInfo: null,
dispatcherHookName: 'EffectEvent',
});
return callback;
}
const Dispatcher: DispatcherType = {
use,
readContext,
@@ -773,6 +794,7 @@ const Dispatcher: DispatcherType = {
useFormState,
useActionState,
useHostTransitionStatus,
useEffectEvent,
useResourceEffect,
};
@@ -962,7 +984,7 @@ function parseHookName(functionName: void | string): string {
startIndex += 'unstable_'.length;
}
if (functionName.slice(startIndex).startsWith('unstable_')) {
if (functionName.slice(startIndex).startsWith('experimental_')) {
startIndex += 'experimental_'.length;
}

View File

@@ -19,6 +19,7 @@ import NestedProps from './NestedProps';
import SimpleValues from './SimpleValues';
import SymbolKeys from './SymbolKeys';
import UseMemoCache from './UseMemoCache';
import UseEffectEvent from './UseEffectEvent';
// TODO Add Immutable JS example
@@ -36,6 +37,7 @@ export default function InspectableElements(): React.Node {
<CircularReferences />
<SymbolKeys />
<UseMemoCache />
<UseEffectEvent />
</Fragment>
);
}

View File

@@ -0,0 +1,32 @@
import * as React from 'react';
const {experimental_useEffectEvent, useState, useEffect} = React;
export default function UseEffectEvent(): React.Node {
return (
<>
<SingleHookCase />
<HookTreeCase />
</>
);
}
function SingleHookCase() {
const onClick = experimental_useEffectEvent(() => {});
return <div onClick={onClick} />;
}
function useCustomHook() {
const [state, setState] = useState();
const onClick = experimental_useEffectEvent(() => {});
useEffect(() => {});
return [state, setState, onClick];
}
function HookTreeCase() {
const onClick = useCustomHook();
return <div onClick={onClick} />;
}