diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index 7d4220460d9..bd0c6107f37 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -6509,7 +6509,6 @@ describe('ReactDOMFizzServer', () => { }); describe('useEffectEvent', () => { - // @gate enableUseEffectEventHook it('can server render a component with useEffectEvent', async () => { const ref = React.createRef(); function App() { @@ -6540,7 +6539,6 @@ describe('ReactDOMFizzServer', () => { expect(getVisibleChildren(container)).toEqual(); }); - // @gate enableUseEffectEventHook it('throws if useEffectEvent is called during a server render', async () => { const logs = []; function App() { @@ -6572,7 +6570,6 @@ describe('ReactDOMFizzServer', () => { expect(reportedServerErrors).toEqual([caughtError]); }); - // @gate enableUseEffectEventHook it('does not guarantee useEffectEvent return values during server rendering are distinct', async () => { function App() { const onClick1 = React.useEffectEvent(() => {}); diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.js b/packages/react-reconciler/src/ReactFiberCommitWork.js index ecacb0c1585..43db744007d 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.js @@ -54,7 +54,6 @@ import { enableScopeAPI, enableUpdaterTracking, enableTransitionTracing, - enableUseEffectEventHook, enableLegacyHidden, disableLegacyMode, enableComponentPerformanceTrack, @@ -500,17 +499,14 @@ function commitBeforeMutationEffectsOnFiber( case FunctionComponent: case ForwardRef: case SimpleMemoComponent: { - if (enableUseEffectEventHook) { - if ((flags & Update) !== NoFlags) { - const updateQueue: FunctionComponentUpdateQueue | null = - (finishedWork.updateQueue: any); - const eventPayloads = - updateQueue !== null ? updateQueue.events : null; - if (eventPayloads !== null) { - for (let ii = 0; ii < eventPayloads.length; ii++) { - const {ref, nextImpl} = eventPayloads[ii]; - ref.impl = nextImpl; - } + if ((flags & Update) !== NoFlags) { + const updateQueue: FunctionComponentUpdateQueue | null = + (finishedWork.updateQueue: any); + const eventPayloads = updateQueue !== null ? updateQueue.events : null; + if (eventPayloads !== null) { + for (let ii = 0; ii < eventPayloads.length; ii++) { + const {ref, nextImpl} = eventPayloads[ii]; + ref.impl = nextImpl; } } } diff --git a/packages/react-reconciler/src/ReactFiberFlags.js b/packages/react-reconciler/src/ReactFiberFlags.js index 7fa1dcb8173..2d8d3f7fd16 100644 --- a/packages/react-reconciler/src/ReactFiberFlags.js +++ b/packages/react-reconciler/src/ReactFiberFlags.js @@ -7,10 +7,7 @@ * @flow */ -import { - enableCreateEventHandleAPI, - enableUseEffectEventHook, -} from 'shared/ReactFeatureFlags'; +import {enableCreateEventHandleAPI} from 'shared/ReactFeatureFlags'; export type Flags = number; @@ -102,12 +99,10 @@ export const BeforeMutationMask: number = // TODO: Only need to visit Deletions during BeforeMutation phase if an // element is focused. Update | ChildDeletion | Visibility - : enableUseEffectEventHook - ? // TODO: The useEffectEvent hook uses the snapshot phase for clean up but it - // really should use the mutation phase for this or at least schedule an - // explicit Snapshot phase flag for this. - Update - : 0); + : // TODO: The useEffectEvent hook uses the snapshot phase for clean up but it + // really should use the mutation phase for this or at least schedule an + // explicit Snapshot phase flag for this. + Update); // For View Transition support we use the snapshot phase to scan the tree for potentially // affected ViewTransition components. diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index 422667c6a12..0450495ff0d 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -38,7 +38,6 @@ import ReactSharedInternals from 'shared/ReactSharedInternals'; import { enableSchedulingProfiler, enableTransitionTracing, - enableUseEffectEventHook, enableLegacyCache, disableLegacyMode, enableNoCloningMemoCache, @@ -3893,10 +3892,8 @@ export const ContextOnlyDispatcher: Dispatcher = { useOptimistic: throwInvalidHookError, useMemoCache: throwInvalidHookError, useCacheRefresh: throwInvalidHookError, + useEffectEvent: throwInvalidHookError, }; -if (enableUseEffectEventHook) { - (ContextOnlyDispatcher: Dispatcher).useEffectEvent = throwInvalidHookError; -} const HooksDispatcherOnMount: Dispatcher = { readContext, @@ -3923,10 +3920,8 @@ const HooksDispatcherOnMount: Dispatcher = { useOptimistic: mountOptimistic, useMemoCache, useCacheRefresh: mountRefresh, + useEffectEvent: mountEvent, }; -if (enableUseEffectEventHook) { - (HooksDispatcherOnMount: Dispatcher).useEffectEvent = mountEvent; -} const HooksDispatcherOnUpdate: Dispatcher = { readContext, @@ -3953,10 +3948,8 @@ const HooksDispatcherOnUpdate: Dispatcher = { useOptimistic: updateOptimistic, useMemoCache, useCacheRefresh: updateRefresh, + useEffectEvent: updateEvent, }; -if (enableUseEffectEventHook) { - (HooksDispatcherOnUpdate: Dispatcher).useEffectEvent = updateEvent; -} const HooksDispatcherOnRerender: Dispatcher = { readContext, @@ -3983,10 +3976,8 @@ const HooksDispatcherOnRerender: Dispatcher = { useOptimistic: rerenderOptimistic, useMemoCache, useCacheRefresh: updateRefresh, + useEffectEvent: updateEvent, }; -if (enableUseEffectEventHook) { - (HooksDispatcherOnRerender: Dispatcher).useEffectEvent = updateEvent; -} let HooksDispatcherOnMountInDEV: Dispatcher | null = null; let HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher | null = null; @@ -4176,17 +4167,14 @@ if (__DEV__) { mountHookTypesDev(); return mountRefresh(); }, + useEffectEvent) => Return>( + callback: F, + ): F { + currentHookNameInDev = 'useEffectEvent'; + mountHookTypesDev(); + return mountEvent(callback); + }, }; - if (enableUseEffectEventHook) { - (HooksDispatcherOnMountInDEV: Dispatcher).useEffectEvent = - function useEffectEvent) => Return>( - callback: F, - ): F { - currentHookNameInDev = 'useEffectEvent'; - mountHookTypesDev(); - return mountEvent(callback); - }; - } HooksDispatcherOnMountWithHookTypesInDEV = { readContext(context: ReactContext): T { @@ -4343,17 +4331,14 @@ if (__DEV__) { updateHookTypesDev(); return mountRefresh(); }, + useEffectEvent) => Return>( + callback: F, + ): F { + currentHookNameInDev = 'useEffectEvent'; + updateHookTypesDev(); + return mountEvent(callback); + }, }; - if (enableUseEffectEventHook) { - (HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher).useEffectEvent = - function useEffectEvent) => Return>( - callback: F, - ): F { - currentHookNameInDev = 'useEffectEvent'; - updateHookTypesDev(); - return mountEvent(callback); - }; - } HooksDispatcherOnUpdateInDEV = { readContext(context: ReactContext): T { @@ -4510,17 +4495,14 @@ if (__DEV__) { updateHookTypesDev(); return updateRefresh(); }, + useEffectEvent) => Return>( + callback: F, + ): F { + currentHookNameInDev = 'useEffectEvent'; + updateHookTypesDev(); + return updateEvent(callback); + }, }; - if (enableUseEffectEventHook) { - (HooksDispatcherOnUpdateInDEV: Dispatcher).useEffectEvent = - function useEffectEvent) => Return>( - callback: F, - ): F { - currentHookNameInDev = 'useEffectEvent'; - updateHookTypesDev(); - return updateEvent(callback); - }; - } HooksDispatcherOnRerenderInDEV = { readContext(context: ReactContext): T { @@ -4677,17 +4659,14 @@ if (__DEV__) { updateHookTypesDev(); return updateRefresh(); }, + useEffectEvent) => Return>( + callback: F, + ): F { + currentHookNameInDev = 'useEffectEvent'; + updateHookTypesDev(); + return updateEvent(callback); + }, }; - if (enableUseEffectEventHook) { - (HooksDispatcherOnRerenderInDEV: Dispatcher).useEffectEvent = - function useEffectEvent) => Return>( - callback: F, - ): F { - currentHookNameInDev = 'useEffectEvent'; - updateHookTypesDev(); - return updateEvent(callback); - }; - } InvalidNestedHooksDispatcherOnMountInDEV = { readContext(context: ReactContext): T { @@ -4868,18 +4847,15 @@ if (__DEV__) { mountHookTypesDev(); return mountRefresh(); }, + useEffectEvent) => Return>( + callback: F, + ): F { + currentHookNameInDev = 'useEffectEvent'; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountEvent(callback); + }, }; - if (enableUseEffectEventHook) { - (InvalidNestedHooksDispatcherOnMountInDEV: Dispatcher).useEffectEvent = - function useEffectEvent) => Return>( - callback: F, - ): F { - currentHookNameInDev = 'useEffectEvent'; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEvent(callback); - }; - } InvalidNestedHooksDispatcherOnUpdateInDEV = { readContext(context: ReactContext): T { @@ -5060,18 +5036,15 @@ if (__DEV__) { updateHookTypesDev(); return updateRefresh(); }, + useEffectEvent) => Return>( + callback: F, + ): F { + currentHookNameInDev = 'useEffectEvent'; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEvent(callback); + }, }; - if (enableUseEffectEventHook) { - (InvalidNestedHooksDispatcherOnUpdateInDEV: Dispatcher).useEffectEvent = - function useEffectEvent) => Return>( - callback: F, - ): F { - currentHookNameInDev = 'useEffectEvent'; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEvent(callback); - }; - } InvalidNestedHooksDispatcherOnRerenderInDEV = { readContext(context: ReactContext): T { @@ -5252,16 +5225,13 @@ if (__DEV__) { updateHookTypesDev(); return updateRefresh(); }, + useEffectEvent) => Return>( + callback: F, + ): F { + currentHookNameInDev = 'useEffectEvent'; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEvent(callback); + }, }; - if (enableUseEffectEventHook) { - (InvalidNestedHooksDispatcherOnRerenderInDEV: Dispatcher).useEffectEvent = - function useEffectEvent) => Return>( - callback: F, - ): F { - currentHookNameInDev = 'useEffectEvent'; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEvent(callback); - }; - } } diff --git a/packages/react-reconciler/src/ReactInternalTypes.js b/packages/react-reconciler/src/ReactInternalTypes.js index ce22050123c..d12c1e38694 100644 --- a/packages/react-reconciler/src/ReactInternalTypes.js +++ b/packages/react-reconciler/src/ReactInternalTypes.js @@ -409,8 +409,7 @@ export type Dispatcher = { create: () => (() => void) | void, deps: Array | void | null, ): void, - // TODO: Non-nullable once `enableUseEffectEventHook` is on everywhere. - useEffectEvent?: ) => mixed>(callback: F) => F, + useEffectEvent: ) => mixed>(callback: F) => F, useInsertionEffect( create: () => (() => void) | void, deps: Array | void | null, diff --git a/packages/react-reconciler/src/__tests__/useEffectEvent-test.js b/packages/react-reconciler/src/__tests__/useEffectEvent-test.js index f263c9af269..2b5af2206b9 100644 --- a/packages/react-reconciler/src/__tests__/useEffectEvent-test.js +++ b/packages/react-reconciler/src/__tests__/useEffectEvent-test.js @@ -53,7 +53,6 @@ describe('useEffectEvent', () => { return ; } - // @gate enableUseEffectEventHook it('memoizes basic case correctly', async () => { class IncrementButton extends React.PureComponent { increment = () => { @@ -129,7 +128,6 @@ describe('useEffectEvent', () => { ); }); - // @gate enableUseEffectEventHook it('can be defined more than once', async () => { class IncrementButton extends React.PureComponent { increment = () => { @@ -191,7 +189,6 @@ describe('useEffectEvent', () => { ); }); - // @gate enableUseEffectEventHook it('does not preserve `this` in event functions', async () => { class GreetButton extends React.PureComponent { greet = () => { @@ -241,7 +238,6 @@ describe('useEffectEvent', () => { ); }); - // @gate enableUseEffectEventHook it('throws when called in render', async () => { class IncrementButton extends React.PureComponent { increment = () => { @@ -275,7 +271,6 @@ describe('useEffectEvent', () => { assertLog([]); }); - // @gate enableUseEffectEventHook it("useLayoutEffect shouldn't re-fire when event handlers change", async () => { class IncrementButton extends React.PureComponent { increment = () => { @@ -375,7 +370,6 @@ describe('useEffectEvent', () => { ); }); - // @gate enableUseEffectEventHook it("useEffect shouldn't re-fire when event handlers change", async () => { class IncrementButton extends React.PureComponent { increment = () => { @@ -474,7 +468,6 @@ describe('useEffectEvent', () => { ); }); - // @gate enableUseEffectEventHook it('is stable in a custom hook', async () => { class IncrementButton extends React.PureComponent { increment = () => { @@ -579,7 +572,6 @@ describe('useEffectEvent', () => { ); }); - // @gate enableUseEffectEventHook it('is mutated before all other effects', async () => { function Counter({value}) { useInsertionEffect(() => { @@ -603,7 +595,6 @@ describe('useEffectEvent', () => { assertLog(['Effect value: 2', 'Event value: 2']); }); - // @gate enableUseEffectEventHook it("doesn't provide a stable identity", async () => { function Counter({shouldRender, value}) { const onClick = useEffectEvent(() => { @@ -642,7 +633,6 @@ describe('useEffectEvent', () => { ]); }); - // @gate enableUseEffectEventHook it('event handlers always see the latest committed value', async () => { let committedEventHandler = null; @@ -692,7 +682,6 @@ describe('useEffectEvent', () => { expect(committedEventHandler()).toBe('Value seen by useEffectEvent: 2'); }); - // @gate enableUseEffectEventHook it('integration: implements docs chat room example', async () => { function createConnection() { let connectedCallback; @@ -781,7 +770,6 @@ describe('useEffectEvent', () => { ); }); - // @gate enableUseEffectEventHook it('integration: implements the docs logVisit example', async () => { class AddToCartButton extends React.PureComponent { addToCart = () => { diff --git a/packages/react-server/src/ReactFizzHooks.js b/packages/react-server/src/ReactFizzHooks.js index 119c2a0778f..24e676fc710 100644 --- a/packages/react-server/src/ReactFizzHooks.js +++ b/packages/react-server/src/ReactFizzHooks.js @@ -38,7 +38,6 @@ import { } from './ReactFizzConfig'; import {createFastHash} from './ReactServerStreamConfig'; -import {enableUseEffectEventHook} from 'shared/ReactFeatureFlags'; import is from 'shared/objectIs'; import { REACT_CONTEXT_TYPE, @@ -833,6 +832,7 @@ export const HooksDispatcher: Dispatcher = supportsClientAPIs useHostTransitionStatus, useMemoCache, useCacheRefresh, + useEffectEvent, } : { readContext, @@ -858,12 +858,9 @@ export const HooksDispatcher: Dispatcher = supportsClientAPIs useOptimistic, useMemoCache, useCacheRefresh, + useEffectEvent, }; -if (enableUseEffectEventHook) { - HooksDispatcher.useEffectEvent = useEffectEvent; -} - export let currentResumableState: null | ResumableState = (null: any); export function setCurrentResumableState( resumableState: null | ResumableState, diff --git a/packages/react-server/src/ReactFlightHooks.js b/packages/react-server/src/ReactFlightHooks.js index ed369be0e9b..d814de46298 100644 --- a/packages/react-server/src/ReactFlightHooks.js +++ b/packages/react-server/src/ReactFlightHooks.js @@ -17,7 +17,6 @@ import { } from 'shared/ReactSymbols'; import {createThenableState, trackUsedThenable} from './ReactFlightThenable'; import {isClientReference} from './ReactFlightServerConfig'; -import {enableUseEffectEventHook} from 'shared/ReactFeatureFlags'; let currentRequest = null; let thenableIndexCounter = 0; @@ -101,10 +100,8 @@ export const HooksDispatcher: Dispatcher = { useCacheRefresh(): (?() => T, ?T) => void { return unsupportedRefresh; }, + useEffectEvent: (unsupportedHook: any), }; -if (enableUseEffectEventHook) { - HooksDispatcher.useEffectEvent = (unsupportedHook: any); -} function unsupportedHook(): void { throw new Error('This Hook is not supported in Server Components.'); diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index ebb287568af..587e4e6a1da 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -118,8 +118,6 @@ export const enableCPUSuspense = __EXPERIMENTAL__; // Test this at Meta before enabling. export const enableNoCloningMemoCache: boolean = false; -export const enableUseEffectEventHook: boolean = true; - // Test in www before enabling in open source. // Enables DOM-server to stream its instruction set as data-attributes // (handled with an MutationObserver) instead of inline-scripts diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index d9a91f8a808..e2674b70fee 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -64,7 +64,6 @@ export const enableTaint: boolean = true; export const enableTransitionTracing: boolean = false; export const enableTrustedTypesIntegration: boolean = false; export const enableUpdaterTracking: boolean = __PROFILE__; -export const enableUseEffectEventHook: boolean = true; export const retryLaneExpirationMs = 5000; export const syncLaneExpirationMs = 250; export const transitionLaneExpirationMs = 5000; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index fa8f336c03f..672c3755108 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -51,7 +51,6 @@ export const enableSuspenseCallback: boolean = false; export const enableTaint: boolean = true; export const enableTransitionTracing: boolean = false; export const enableTrustedTypesIntegration: boolean = false; -export const enableUseEffectEventHook: boolean = true; export const passChildrenWhenCloningPersistedNodes: boolean = false; export const renameElementSymbol: boolean = true; export const retryLaneExpirationMs = 5000; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index acf3847bd06..67c08d94367 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -32,7 +32,6 @@ export const disableTextareaChildren: boolean = false; export const enableSuspenseAvoidThisFallback: boolean = false; export const enableCPUSuspense: boolean = false; export const enableNoCloningMemoCache: boolean = false; -export const enableUseEffectEventHook: boolean = true; export const enableLegacyFBSupport: boolean = false; export const enableMoveBefore: boolean = false; export const enableHiddenSubtreeInsertionEffectCleanup: boolean = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js index 5d3a5513018..a0ee01baa7d 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js @@ -49,7 +49,6 @@ export const enableTaint = true; export const enableTransitionTracing = false; export const enableTrustedTypesIntegration = false; export const enableUpdaterTracking = false; -export const enableUseEffectEventHook = true; export const passChildrenWhenCloningPersistedNodes = false; export const renameElementSymbol = false; export const retryLaneExpirationMs = 5000; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 553be202c45..058fd752d6e 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -34,7 +34,6 @@ export const disableTextareaChildren: boolean = false; export const enableSuspenseAvoidThisFallback: boolean = true; export const enableCPUSuspense: boolean = false; export const enableNoCloningMemoCache: boolean = false; -export const enableUseEffectEventHook: boolean = true; export const enableLegacyFBSupport: boolean = false; export const enableMoveBefore: boolean = false; export const enableHiddenSubtreeInsertionEffectCleanup: boolean = true; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 87801a9658f..0752f266afc 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -49,7 +49,6 @@ export const enableUpdaterTracking = __PROFILE__; export const enableSuspenseAvoidThisFallback: boolean = true; export const enableCPUSuspense: boolean = true; -export const enableUseEffectEventHook: boolean = true; export const enableMoveBefore: boolean = false; export const disableInputAttributeSyncing: boolean = false; export const enableLegacyFBSupport: boolean = true;