Skip to content

Commit 777d296

Browse files
committed
Cleanup enableFormActions flag
1 parent 6708115 commit 777d296

29 files changed

+182
-308
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2672,7 +2672,7 @@ describe('ReactHooksInspectionIntegration', () => {
26722672
`);
26732673
});
26742674

2675-
// @gate enableFormActions && enableAsyncActions
2675+
// @gate enableAsyncActions
26762676
it('should support useFormState hook', async () => {
26772677
function Foo() {
26782678
const [value] = ReactDOM.useFormState(function increment(n) {

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

Lines changed: 70 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ import {
6969
enableBigIntSupport,
7070
enableCustomElementPropertySupport,
7171
enableClientRenderFallbackOnTextMismatch,
72-
enableFormActions,
7372
disableIEWorkarounds,
7473
enableTrustedTypesIntegration,
7574
enableFilterEmptyStringAttributesDOM,
@@ -498,71 +497,54 @@ function setProp(
498497
if (__DEV__) {
499498
validateFormActionInDevelopment(tag, key, value, props);
500499
}
501-
if (enableFormActions) {
502-
if (typeof value === 'function') {
503-
// Set a javascript URL that doesn't do anything. We don't expect this to be invoked
504-
// because we'll preventDefault, but it can happen if a form is manually submitted or
505-
// if someone calls stopPropagation before React gets the event.
506-
// If CSP is used to block javascript: URLs that's fine too. It just won't show this
507-
// error message but the URL will be logged.
508-
domElement.setAttribute(
509-
key,
510-
// eslint-disable-next-line no-script-url
511-
"javascript:throw new Error('" +
512-
'A React form was unexpectedly submitted. If you called form.submit() manually, ' +
513-
"consider using form.requestSubmit() instead. If you\\'re trying to use " +
514-
'event.stopPropagation() in a submit event handler, consider also calling ' +
515-
'event.preventDefault().' +
516-
"')",
517-
);
518-
break;
519-
} else if (typeof prevValue === 'function') {
520-
// When we're switching off a Server Action that was originally hydrated.
521-
// The server control these fields during SSR that are now trailing.
522-
// The regular diffing doesn't apply since we compare against the previous props.
523-
// Instead, we need to force them to be set to whatever they should be now.
524-
// This would be a lot cleaner if we did this whole fork in the per-tag approach.
525-
if (key === 'formAction') {
526-
if (tag !== 'input') {
527-
// Setting the name here isn't completely safe for inputs if this is switching
528-
// to become a radio button. In that case we let the tag based override take
529-
// control.
530-
setProp(domElement, tag, 'name', props.name, props, null);
531-
}
532-
setProp(
533-
domElement,
534-
tag,
535-
'formEncType',
536-
props.formEncType,
537-
props,
538-
null,
539-
);
540-
setProp(
541-
domElement,
542-
tag,
543-
'formMethod',
544-
props.formMethod,
545-
props,
546-
null,
547-
);
548-
setProp(
549-
domElement,
550-
tag,
551-
'formTarget',
552-
props.formTarget,
553-
props,
554-
null,
555-
);
556-
} else {
557-
setProp(domElement, tag, 'encType', props.encType, props, null);
558-
setProp(domElement, tag, 'method', props.method, props, null);
559-
setProp(domElement, tag, 'target', props.target, props, null);
500+
if (typeof value === 'function') {
501+
// Set a javascript URL that doesn't do anything. We don't expect this to be invoked
502+
// because we'll preventDefault, but it can happen if a form is manually submitted or
503+
// if someone calls stopPropagation before React gets the event.
504+
// If CSP is used to block javascript: URLs that's fine too. It just won't show this
505+
// error message but the URL will be logged.
506+
domElement.setAttribute(
507+
key,
508+
// eslint-disable-next-line no-script-url
509+
"javascript:throw new Error('" +
510+
'A React form was unexpectedly submitted. If you called form.submit() manually, ' +
511+
"consider using form.requestSubmit() instead. If you\\'re trying to use " +
512+
'event.stopPropagation() in a submit event handler, consider also calling ' +
513+
'event.preventDefault().' +
514+
"')",
515+
);
516+
break;
517+
} else if (typeof prevValue === 'function') {
518+
// When we're switching off a Server Action that was originally hydrated.
519+
// The server control these fields during SSR that are now trailing.
520+
// The regular diffing doesn't apply since we compare against the previous props.
521+
// Instead, we need to force them to be set to whatever they should be now.
522+
// This would be a lot cleaner if we did this whole fork in the per-tag approach.
523+
if (key === 'formAction') {
524+
if (tag !== 'input') {
525+
// Setting the name here isn't completely safe for inputs if this is switching
526+
// to become a radio button. In that case we let the tag based override take
527+
// control.
528+
setProp(domElement, tag, 'name', props.name, props, null);
560529
}
530+
setProp(
531+
domElement,
532+
tag,
533+
'formEncType',
534+
props.formEncType,
535+
props,
536+
null,
537+
);
538+
setProp(domElement, tag, 'formMethod', props.formMethod, props, null);
539+
setProp(domElement, tag, 'formTarget', props.formTarget, props, null);
540+
} else {
541+
setProp(domElement, tag, 'encType', props.encType, props, null);
542+
setProp(domElement, tag, 'method', props.method, props, null);
543+
setProp(domElement, tag, 'target', props.target, props, null);
561544
}
562545
}
563546
if (
564547
value == null ||
565-
(!enableFormActions && typeof value === 'function') ||
566548
typeof value === 'symbol' ||
567549
typeof value === 'boolean'
568550
) {
@@ -2435,35 +2417,33 @@ function diffHydratedGenericElement(
24352417
);
24362418
continue;
24372419
case 'action':
2438-
case 'formAction':
2439-
if (enableFormActions) {
2440-
const serverValue = domElement.getAttribute(propKey);
2441-
if (typeof value === 'function') {
2442-
extraAttributes.delete(propKey.toLowerCase());
2443-
// The server can set these extra properties to implement actions.
2444-
// So we remove them from the extra attributes warnings.
2445-
if (propKey === 'formAction') {
2446-
extraAttributes.delete('name');
2447-
extraAttributes.delete('formenctype');
2448-
extraAttributes.delete('formmethod');
2449-
extraAttributes.delete('formtarget');
2450-
} else {
2451-
extraAttributes.delete('enctype');
2452-
extraAttributes.delete('method');
2453-
extraAttributes.delete('target');
2454-
}
2455-
// Ideally we should be able to warn if the server value was not a function
2456-
// however since the function can return any of these attributes any way it
2457-
// wants as a custom progressive enhancement, there's nothing to compare to.
2458-
// We can check if the function has the $FORM_ACTION property on the client
2459-
// and if it's not, warn, but that's an unnecessary constraint that they
2460-
// have to have the extra extension that doesn't do anything on the client.
2461-
continue;
2462-
} else if (serverValue === EXPECTED_FORM_ACTION_URL) {
2463-
extraAttributes.delete(propKey.toLowerCase());
2464-
warnForPropDifference(propKey, 'function', value);
2465-
continue;
2420+
case 'formAction': {
2421+
const serverValue = domElement.getAttribute(propKey);
2422+
if (typeof value === 'function') {
2423+
extraAttributes.delete(propKey.toLowerCase());
2424+
// The server can set these extra properties to implement actions.
2425+
// So we remove them from the extra attributes warnings.
2426+
if (propKey === 'formAction') {
2427+
extraAttributes.delete('name');
2428+
extraAttributes.delete('formenctype');
2429+
extraAttributes.delete('formmethod');
2430+
extraAttributes.delete('formtarget');
2431+
} else {
2432+
extraAttributes.delete('enctype');
2433+
extraAttributes.delete('method');
2434+
extraAttributes.delete('target');
24662435
}
2436+
// Ideally we should be able to warn if the server value was not a function
2437+
// however since the function can return any of these attributes any way it
2438+
// wants as a custom progressive enhancement, there's nothing to compare to.
2439+
// We can check if the function has the $FORM_ACTION property on the client
2440+
// and if it's not, warn, but that's an unnecessary constraint that they
2441+
// have to have the extra extension that doesn't do anything on the client.
2442+
continue;
2443+
} else if (serverValue === EXPECTED_FORM_ACTION_URL) {
2444+
extraAttributes.delete(propKey.toLowerCase());
2445+
warnForPropDifference(propKey, 'function', value);
2446+
continue;
24672447
}
24682448
hydrateSanitizedAttribute(
24692449
domElement,
@@ -2473,6 +2453,7 @@ function diffHydratedGenericElement(
24732453
extraAttributes,
24742454
);
24752455
continue;
2456+
}
24762457
case 'xlinkHref':
24772458
hydrateSanitizedAttribute(
24782459
domElement,

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

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ import {
9393
enableScopeAPI,
9494
enableFloat,
9595
enableTrustedTypesIntegration,
96-
enableFormActions,
9796
enableAsyncActions,
9897
} from 'shared/ReactFeatureFlags';
9998
import {
@@ -1041,11 +1040,7 @@ export function canHydrateInstance(
10411040
if (element.nodeName.toLowerCase() !== type.toLowerCase()) {
10421041
if (!inRootOrSingleton) {
10431042
// Usually we error for mismatched tags.
1044-
if (
1045-
enableFormActions &&
1046-
element.nodeName === 'INPUT' &&
1047-
(element: any).type === 'hidden'
1048-
) {
1043+
if (element.nodeName === 'INPUT' && (element: any).type === 'hidden') {
10491044
// If we have extra hidden inputs, we don't mismatch. This allows us to embed
10501045
// extra form data in the original form.
10511046
} else {
@@ -1055,11 +1050,7 @@ export function canHydrateInstance(
10551050
// In root or singleton parents we skip past mismatched instances.
10561051
} else if (!inRootOrSingleton) {
10571052
// Match
1058-
if (
1059-
enableFormActions &&
1060-
type === 'input' &&
1061-
(element: any).type === 'hidden'
1062-
) {
1053+
if (type === 'input' && (element: any).type === 'hidden') {
10631054
if (__DEV__) {
10641055
checkAttributeStringCoercion(anyProps.name, 'name');
10651056
}
@@ -1191,7 +1182,6 @@ export function canHydrateTextInstance(
11911182

11921183
while (instance.nodeType !== TEXT_NODE) {
11931184
if (
1194-
enableFormActions &&
11951185
instance.nodeType === ELEMENT_NODE &&
11961186
instance.nodeName === 'INPUT' &&
11971187
(instance: any).type === 'hidden'
@@ -1317,8 +1307,7 @@ function getNextHydratable(node: ?Node) {
13171307
nodeData === SUSPENSE_START_DATA ||
13181308
nodeData === SUSPENSE_FALLBACK_START_DATA ||
13191309
nodeData === SUSPENSE_PENDING_START_DATA ||
1320-
(enableFormActions &&
1321-
enableAsyncActions &&
1310+
(enableAsyncActions &&
13221311
(nodeData === FORM_STATE_IS_MATCHING ||
13231312
nodeData === FORM_STATE_IS_NOT_MATCHING))
13241313
) {
@@ -1513,9 +1502,7 @@ export function commitHydratedSuspenseInstance(
15131502
export function shouldDeleteUnhydratedTailInstances(
15141503
parentType: string,
15151504
): boolean {
1516-
return (
1517-
!enableFormActions || (parentType !== 'form' && parentType !== 'button')
1518-
);
1505+
return parentType !== 'form' && parentType !== 'button';
15191506
}
15201507

15211508
export function didNotMatchHydratedContainerTextInstance(

packages/react-dom-bindings/src/events/DOMPluginEventSystem.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ import {
5353
enableCreateEventHandleAPI,
5454
enableScopeAPI,
5555
enableFloat,
56-
enableFormActions,
5756
} from 'shared/ReactFeatureFlags';
5857
import {createEventListenerWrapperWithPriority} from './ReactDOMEventListener';
5958
import {
@@ -170,17 +169,15 @@ function extractEvents(
170169
eventSystemFlags,
171170
targetContainer,
172171
);
173-
if (enableFormActions) {
174-
FormActionEventPlugin.extractEvents(
175-
dispatchQueue,
176-
domEventName,
177-
targetInst,
178-
nativeEvent,
179-
nativeEventTarget,
180-
eventSystemFlags,
181-
targetContainer,
182-
);
183-
}
172+
FormActionEventPlugin.extractEvents(
173+
dispatchQueue,
174+
domEventName,
175+
targetInst,
176+
nativeEvent,
177+
nativeEventTarget,
178+
eventSystemFlags,
179+
targetContainer,
180+
);
184181
}
185182
}
186183

0 commit comments

Comments
 (0)