Skip to content

Commit 4b4420e

Browse files
committed
Remove enableAsyncActions
1 parent 441804f commit 4b4420e

24 files changed

+381
-663
lines changed

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2581,7 +2581,6 @@ describe('ReactHooksInspectionIntegration', () => {
25812581
`);
25822582
});
25832583

2584-
// @gate enableAsyncActions
25852584
it('should support useOptimistic hook', async () => {
25862585
const useOptimistic = React.useOptimistic;
25872586
function Foo() {
@@ -2647,7 +2646,6 @@ describe('ReactHooksInspectionIntegration', () => {
26472646
`);
26482647
});
26492648

2650-
// @gate enableAsyncActions
26512649
it('should support useActionState hook', async () => {
26522650
function Foo() {
26532651
const [value] = React.useActionState(function increment(n) {

packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ import {
9191
enableCreateEventHandleAPI,
9292
enableScopeAPI,
9393
enableTrustedTypesIntegration,
94-
enableAsyncActions,
9594
disableLegacyMode,
9695
enableMoveBefore,
9796
} from 'shared/ReactFeatureFlags';
@@ -1378,9 +1377,8 @@ function getNextHydratable(node: ?Node) {
13781377
nodeData === SUSPENSE_START_DATA ||
13791378
nodeData === SUSPENSE_FALLBACK_START_DATA ||
13801379
nodeData === SUSPENSE_PENDING_START_DATA ||
1381-
(enableAsyncActions &&
1382-
(nodeData === FORM_STATE_IS_MATCHING ||
1383-
nodeData === FORM_STATE_IS_NOT_MATCHING))
1380+
nodeData === FORM_STATE_IS_MATCHING ||
1381+
nodeData === FORM_STATE_IS_NOT_MATCHING
13841382
) {
13851383
break;
13861384
}

packages/react-dom-bindings/src/shared/ReactDOMFormActions.js

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import type {Dispatcher} from 'react-reconciler/src/ReactInternalTypes';
1111
import type {Awaited} from 'shared/ReactTypes';
1212

13-
import {enableAsyncActions} from 'shared/ReactFeatureFlags';
1413
import ReactSharedInternals from 'shared/ReactSharedInternals';
1514
import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
1615

@@ -66,27 +65,19 @@ function resolveDispatcher() {
6665
}
6766

6867
export function useFormStatus(): FormStatus {
69-
if (!enableAsyncActions) {
70-
throw new Error('Not implemented.');
71-
} else {
72-
const dispatcher = resolveDispatcher();
73-
// $FlowFixMe[not-a-function] We know this exists because of the feature check above.
74-
return dispatcher.useHostTransitionStatus();
75-
}
68+
const dispatcher = resolveDispatcher();
69+
// $FlowFixMe[not-a-function] We know this exists because of the feature check above.
70+
return dispatcher.useHostTransitionStatus();
7671
}
7772

7873
export function useFormState<S, P>(
7974
action: (Awaited<S>, P) => S,
8075
initialState: Awaited<S>,
8176
permalink?: string,
8277
): [Awaited<S>, (P) => void, boolean] {
83-
if (!enableAsyncActions) {
84-
throw new Error('Not implemented.');
85-
} else {
86-
const dispatcher = resolveDispatcher();
87-
// $FlowFixMe[not-a-function] This is unstable, thus optional
88-
return dispatcher.useFormState(action, initialState, permalink);
89-
}
78+
const dispatcher = resolveDispatcher();
79+
// $FlowFixMe[not-a-function] This is unstable, thus optional
80+
return dispatcher.useFormState(action, initialState, permalink);
9081
}
9182

9283
export function requestFormReset(form: HTMLFormElement) {

packages/react-dom/src/__tests__/ReactDOMFizzForm-test.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,6 @@ describe('ReactDOMFizzForm', () => {
398398
expect(buttonRef.current.hasAttribute('formTarget')).toBe(false);
399399
});
400400

401-
// @gate enableAsyncActions
402401
it('useFormStatus is not pending during server render', async () => {
403402
function App() {
404403
const {pending} = useFormStatus();
@@ -488,7 +487,6 @@ describe('ReactDOMFizzForm', () => {
488487
expect(rootActionCalled).toBe(false);
489488
});
490489

491-
// @gate enableAsyncActions
492490
it('useOptimistic returns passthrough value', async () => {
493491
function App() {
494492
const [optimisticState] = useOptimistic('hi');
@@ -507,7 +505,6 @@ describe('ReactDOMFizzForm', () => {
507505
expect(container.textContent).toBe('hi');
508506
});
509507

510-
// @gate enableAsyncActions
511508
it('useActionState returns initial state', async () => {
512509
async function action(state) {
513510
return state;

packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6330,7 +6330,6 @@ describe('ReactDOMFizzServer', () => {
63306330
expect(getVisibleChildren(container)).toEqual('Hi');
63316331
});
63326332

6333-
// @gate enableAsyncActions
63346333
it('useActionState hydrates without a mismatch', async () => {
63356334
// This is testing an implementation detail: useActionState emits comment
63366335
// nodes into the SSR stream, so this checks that they are handled correctly
@@ -6383,7 +6382,6 @@ describe('ReactDOMFizzServer', () => {
63836382
expect(childRef.current).toBe(child);
63846383
});
63856384

6386-
// @gate enableAsyncActions
63876385
it("useActionState hydrates without a mismatch if there's a render phase update", async () => {
63886386
async function action(state) {
63896387
return state;

packages/react-dom/src/__tests__/ReactDOMForm-test.js

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,6 @@ describe('ReactDOMForm', () => {
669669
expect(actionCalled).toBe(false);
670670
});
671671

672-
// @gate enableAsyncActions
673672
it('form actions are transitions', async () => {
674673
const formRef = React.createRef();
675674

@@ -707,7 +706,6 @@ describe('ReactDOMForm', () => {
707706
expect(container.textContent).toBe('Updated');
708707
});
709708

710-
// @gate enableAsyncActions
711709
it('multiple form actions', async () => {
712710
const formRef = React.createRef();
713711

@@ -798,12 +796,6 @@ describe('ReactDOMForm', () => {
798796
});
799797

800798
it('sync errors in form actions can be captured by an error boundary', async () => {
801-
if (gate(flags => !flags.enableAsyncActions)) {
802-
// TODO: Uncaught JSDOM errors fail the test after the scope has finished
803-
// so don't work with the `gate` mechanism.
804-
return;
805-
}
806-
807799
class ErrorBoundary extends React.Component {
808800
state = {error: null};
809801
static getDerivedStateFromError(error) {
@@ -844,12 +836,6 @@ describe('ReactDOMForm', () => {
844836
});
845837

846838
it('async errors in form actions can be captured by an error boundary', async () => {
847-
if (gate(flags => !flags.enableAsyncActions)) {
848-
// TODO: Uncaught JSDOM errors fail the test after the scope has finished
849-
// so don't work with the `gate` mechanism.
850-
return;
851-
}
852-
853839
class ErrorBoundary extends React.Component {
854840
state = {error: null};
855841
static getDerivedStateFromError(error) {
@@ -895,7 +881,6 @@ describe('ReactDOMForm', () => {
895881
expect(container.textContent).toBe('Oh no!');
896882
});
897883

898-
// @gate enableAsyncActions
899884
it('useFormStatus reads the status of a pending form action', async () => {
900885
const formRef = React.createRef();
901886

@@ -992,7 +977,6 @@ describe('ReactDOMForm', () => {
992977
);
993978
});
994979

995-
// @gate enableAsyncActions
996980
it('useActionState updates state asynchronously and queues multiple actions', async () => {
997981
let actionCounter = 0;
998982
async function action(state, type) {
@@ -1052,7 +1036,6 @@ describe('ReactDOMForm', () => {
10521036
expect(container.textContent).toBe('2');
10531037
});
10541038

1055-
// @gate enableAsyncActions
10561039
it('useActionState supports inline actions', async () => {
10571040
let increment;
10581041
function App({stepSize}) {
@@ -1084,7 +1067,6 @@ describe('ReactDOMForm', () => {
10841067
assertLog(['Pending 1', '11']);
10851068
});
10861069

1087-
// @gate enableAsyncActions
10881070
it('useActionState: dispatch throws if called during render', async () => {
10891071
function App() {
10901072
const [state, dispatch, isPending] = useActionState(async () => {}, 0);
@@ -1100,7 +1082,6 @@ describe('ReactDOMForm', () => {
11001082
});
11011083
});
11021084

1103-
// @gate enableAsyncActions
11041085
it('useActionState: queues multiple actions and runs them in order', async () => {
11051086
let action;
11061087
function App() {
@@ -1132,7 +1113,6 @@ describe('ReactDOMForm', () => {
11321113
expect(container.textContent).toBe('D');
11331114
});
11341115

1135-
// @gate enableAsyncActions
11361116
it(
11371117
'useActionState: when calling a queued action, uses the implementation ' +
11381118
'that was current at the time it was dispatched, not the most recent one',
@@ -1179,7 +1159,6 @@ describe('ReactDOMForm', () => {
11791159
},
11801160
);
11811161

1182-
// @gate enableAsyncActions
11831162
it('useActionState: works if action is sync', async () => {
11841163
let increment;
11851164
function App({stepSize}) {
@@ -1211,7 +1190,6 @@ describe('ReactDOMForm', () => {
12111190
assertLog(['Pending 1', '11']);
12121191
});
12131192

1214-
// @gate enableAsyncActions
12151193
it('useActionState: can mix sync and async actions', async () => {
12161194
let action;
12171195
function App() {
@@ -1239,7 +1217,6 @@ describe('ReactDOMForm', () => {
12391217
expect(container.textContent).toBe('E');
12401218
});
12411219

1242-
// @gate enableAsyncActions
12431220
it('useActionState: error handling (sync action)', async () => {
12441221
class ErrorBoundary extends React.Component {
12451222
state = {error: null};
@@ -1288,7 +1265,6 @@ describe('ReactDOMForm', () => {
12881265
expect(container.textContent).toBe('Caught an error: Oops!');
12891266
});
12901267

1291-
// @gate enableAsyncActions
12921268
it('useActionState: error handling (async action)', async () => {
12931269
class ErrorBoundary extends React.Component {
12941270
state = {error: null};
@@ -1394,7 +1370,6 @@ describe('ReactDOMForm', () => {
13941370
expect(container.textContent).toBe('Caught an error: Oops!');
13951371
});
13961372

1397-
// @gate enableAsyncActions
13981373
it('useActionState works in StrictMode', async () => {
13991374
let actionCounter = 0;
14001375
async function action(state, type) {

packages/react-dom/src/client/ReactDOMRoot.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import type {
1616
import {isValidContainer} from 'react-dom-bindings/src/client/ReactDOMContainer';
1717
import {queueExplicitHydrationTarget} from 'react-dom-bindings/src/events/ReactDOMEventReplaying';
1818
import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
19-
import {enableAsyncActions} from 'shared/ReactFeatureFlags';
2019

2120
export type RootType = {
2221
render(children: ReactNodeList): void,
@@ -305,10 +304,8 @@ export function hydrateRoot(
305304
if (options.unstable_transitionCallbacks !== undefined) {
306305
transitionCallbacks = options.unstable_transitionCallbacks;
307306
}
308-
if (enableAsyncActions) {
309-
if (options.formState !== undefined) {
310-
formState = options.formState;
311-
}
307+
if (options.formState !== undefined) {
308+
formState = options.formState;
312309
}
313310
}
314311

packages/react-reconciler/src/ReactFiberBeginWork.js

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ import {
106106
enableTransitionTracing,
107107
enableLegacyHidden,
108108
enableCPUSuspense,
109-
enableAsyncActions,
110109
enablePostpone,
111110
enableRenderableContext,
112111
disableLegacyMode,
@@ -1619,55 +1618,53 @@ function updateHostComponent(
16191618
workInProgress.flags |= ContentReset;
16201619
}
16211620

1622-
if (enableAsyncActions) {
1623-
const memoizedState = workInProgress.memoizedState;
1624-
if (memoizedState !== null) {
1625-
// This fiber has been upgraded to a stateful component. The only way
1626-
// happens currently is for form actions. We use hooks to track the
1627-
// pending and error state of the form.
1628-
//
1629-
// Once a fiber is upgraded to be stateful, it remains stateful for the
1630-
// rest of its lifetime.
1631-
const newState = renderTransitionAwareHostComponentWithHooks(
1632-
current,
1633-
workInProgress,
1634-
renderLanes,
1635-
);
1621+
const memoizedState = workInProgress.memoizedState;
1622+
if (memoizedState !== null) {
1623+
// This fiber has been upgraded to a stateful component. The only way
1624+
// happens currently is for form actions. We use hooks to track the
1625+
// pending and error state of the form.
1626+
//
1627+
// Once a fiber is upgraded to be stateful, it remains stateful for the
1628+
// rest of its lifetime.
1629+
const newState = renderTransitionAwareHostComponentWithHooks(
1630+
current,
1631+
workInProgress,
1632+
renderLanes,
1633+
);
16361634

1637-
// If the transition state changed, propagate the change to all the
1638-
// descendents. We use Context as an implementation detail for this.
1639-
//
1640-
// This is intentionally set here instead of pushHostContext because
1641-
// pushHostContext gets called before we process the state hook, to avoid
1642-
// a state mismatch in the event that something suspends.
1643-
//
1644-
// NOTE: This assumes that there cannot be nested transition providers,
1645-
// because the only renderer that implements this feature is React DOM,
1646-
// and forms cannot be nested. If we did support nested providers, then
1647-
// we would need to push a context value even for host fibers that
1648-
// haven't been upgraded yet.
1649-
if (isPrimaryRenderer) {
1650-
HostTransitionContext._currentValue = newState;
1651-
} else {
1652-
HostTransitionContext._currentValue2 = newState;
1653-
}
1654-
if (enableLazyContextPropagation) {
1655-
// In the lazy propagation implementation, we don't scan for matching
1656-
// consumers until something bails out.
1657-
} else {
1658-
if (didReceiveUpdate) {
1659-
if (current !== null) {
1660-
const oldStateHook: Hook = current.memoizedState;
1661-
const oldState: TransitionStatus = oldStateHook.memoizedState;
1662-
// This uses regular equality instead of Object.is because we assume
1663-
// that host transition state doesn't include NaN as a valid type.
1664-
if (oldState !== newState) {
1665-
propagateContextChange(
1666-
workInProgress,
1667-
HostTransitionContext,
1668-
renderLanes,
1669-
);
1670-
}
1635+
// If the transition state changed, propagate the change to all the
1636+
// descendents. We use Context as an implementation detail for this.
1637+
//
1638+
// This is intentionally set here instead of pushHostContext because
1639+
// pushHostContext gets called before we process the state hook, to avoid
1640+
// a state mismatch in the event that something suspends.
1641+
//
1642+
// NOTE: This assumes that there cannot be nested transition providers,
1643+
// because the only renderer that implements this feature is React DOM,
1644+
// and forms cannot be nested. If we did support nested providers, then
1645+
// we would need to push a context value even for host fibers that
1646+
// haven't been upgraded yet.
1647+
if (isPrimaryRenderer) {
1648+
HostTransitionContext._currentValue = newState;
1649+
} else {
1650+
HostTransitionContext._currentValue2 = newState;
1651+
}
1652+
if (enableLazyContextPropagation) {
1653+
// In the lazy propagation implementation, we don't scan for matching
1654+
// consumers until something bails out.
1655+
} else {
1656+
if (didReceiveUpdate) {
1657+
if (current !== null) {
1658+
const oldStateHook: Hook = current.memoizedState;
1659+
const oldState: TransitionStatus = oldStateHook.memoizedState;
1660+
// This uses regular equality instead of Object.is because we assume
1661+
// that host transition state doesn't include NaN as a valid type.
1662+
if (oldState !== newState) {
1663+
propagateContextChange(
1664+
workInProgress,
1665+
HostTransitionContext,
1666+
renderLanes,
1667+
);
16711668
}
16721669
}
16731670
}

0 commit comments

Comments
 (0)