diff --git a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js index ac76fafd5ad86..cb16e40718878 100644 --- a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js +++ b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js @@ -102,6 +102,7 @@ import {listenToAllSupportedEvents} from '../events/DOMPluginEventSystem'; import {validateLinkPropsForStyleResource} from '../shared/ReactDOMResourceValidation'; import escapeSelectorAttributeValueInsideDoubleQuotes from './escapeSelectorAttributeValueInsideDoubleQuotes'; import {flushSyncWork as flushSyncWorkOnAllRoots} from 'react-reconciler/src/ReactFiberWorkLoop'; +import {requestFormReset as requestFormResetOnFiber} from 'react-reconciler/src/ReactFiberHooks'; import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals'; @@ -1928,6 +1929,7 @@ ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */ = { f /* flushSyncWork */: disableLegacyMode ? flushSyncWork : previousDispatcher.f /* flushSyncWork */, + r: requestFormReset, D /* prefetchDNS */: prefetchDNS, C /* preconnect */: preconnect, L /* preload */: preload, @@ -1951,6 +1953,17 @@ function flushSyncWork() { } } +function requestFormReset(form: HTMLFormElement) { + previousDispatcher.r(/* requestFormReset */ form); + const formInst = getInstanceFromNodeDOMTree(form); + if (formInst !== null) { + requestFormResetOnFiber(formInst); + } else { + // TODO: What if none of the dispatchers find a matching form instance? + // Should we detect this in dev and warn? + } +} + // We expect this to get inlined. It is a function mostly to communicate the special nature of // how we resolve the HoistableRoot for ReactDOM.pre*() methods. Because we support calling // these methods outside of render there is no way to know which Document or ShadowRoot is 'scoped' diff --git a/packages/react-dom-bindings/src/server/ReactDOMFlightServerHostDispatcher.js b/packages/react-dom-bindings/src/server/ReactDOMFlightServerHostDispatcher.js index 602452f67e2f3..3303c07cfb4f3 100644 --- a/packages/react-dom-bindings/src/server/ReactDOMFlightServerHostDispatcher.js +++ b/packages/react-dom-bindings/src/server/ReactDOMFlightServerHostDispatcher.js @@ -28,6 +28,7 @@ const previousDispatcher = ReactDOMSharedInternals.d; /* ReactDOMCurrentDispatcher */ ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */ = { f /* flushSyncWork */: previousDispatcher.f /* flushSyncWork */, + r /* requestFormReset */: previousDispatcher.r /* requestFormReset */, D /* prefetchDNS */: prefetchDNS, C /* preconnect */: preconnect, L /* preload */: preload, diff --git a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js index 91baeef4a1bff..d246b4c487973 100644 --- a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js +++ b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js @@ -88,6 +88,7 @@ const previousDispatcher = ReactDOMSharedInternals.d; /* ReactDOMCurrentDispatcher */ ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */ = { f /* flushSyncWork */: previousDispatcher.f /* flushSyncWork */, + r /* requestFormReset */: previousDispatcher.r /* requestFormReset */, D /* prefetchDNS */: prefetchDNS, C /* preconnect */: preconnect, L /* preload */: preload, diff --git a/packages/react-dom-bindings/src/shared/ReactDOMFormActions.js b/packages/react-dom-bindings/src/shared/ReactDOMFormActions.js index 42967f7ce499b..0b3f478e33b19 100644 --- a/packages/react-dom-bindings/src/shared/ReactDOMFormActions.js +++ b/packages/react-dom-bindings/src/shared/ReactDOMFormActions.js @@ -12,6 +12,7 @@ import type {Awaited} from 'shared/ReactTypes'; import {enableAsyncActions} from 'shared/ReactFeatureFlags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; +import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals'; type FormStatusNotPending = {| pending: false, @@ -87,3 +88,8 @@ export function useFormState( return dispatcher.useFormState(action, initialState, permalink); } } + +export function requestFormReset(form: HTMLFormElement) { + ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */ + .r(/* requestFormReset */ form); +} diff --git a/packages/react-dom/index.classic.fb.js b/packages/react-dom/index.classic.fb.js index a565a91f43b1f..63c20f7e51bfe 100644 --- a/packages/react-dom/index.classic.fb.js +++ b/packages/react-dom/index.classic.fb.js @@ -25,6 +25,7 @@ export { unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority. useFormStatus, useFormState, + requestFormReset, prefetchDNS, preconnect, preload, diff --git a/packages/react-dom/index.experimental.js b/packages/react-dom/index.experimental.js index f2d3c27aea0c5..0cc5ef13e3698 100644 --- a/packages/react-dom/index.experimental.js +++ b/packages/react-dom/index.experimental.js @@ -17,6 +17,7 @@ export { unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority. useFormStatus, useFormState, + requestFormReset, prefetchDNS, preconnect, preload, diff --git a/packages/react-dom/index.js b/packages/react-dom/index.js index 50ad087dfaf6c..b6f85ce628c57 100644 --- a/packages/react-dom/index.js +++ b/packages/react-dom/index.js @@ -20,6 +20,7 @@ export { unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority. useFormStatus, useFormState, + requestFormReset, prefetchDNS, preconnect, preload, diff --git a/packages/react-dom/index.modern.fb.js b/packages/react-dom/index.modern.fb.js index 0d2fa4b4dccbd..861febfa5e37b 100644 --- a/packages/react-dom/index.modern.fb.js +++ b/packages/react-dom/index.modern.fb.js @@ -16,6 +16,7 @@ export { unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority. useFormStatus, useFormState, + requestFormReset, prefetchDNS, preconnect, preload, diff --git a/packages/react-dom/index.stable.js b/packages/react-dom/index.stable.js index a9306083c0e61..f5ed138d67ab6 100644 --- a/packages/react-dom/index.stable.js +++ b/packages/react-dom/index.stable.js @@ -16,6 +16,7 @@ export { unstable_batchedUpdates, useFormStatus, useFormState, + requestFormReset, prefetchDNS, preconnect, preload, diff --git a/packages/react-dom/src/ReactDOMSharedInternals.js b/packages/react-dom/src/ReactDOMSharedInternals.js index 50f19f563c9ad..655f23acd6725 100644 --- a/packages/react-dom/src/ReactDOMSharedInternals.js +++ b/packages/react-dom/src/ReactDOMSharedInternals.js @@ -31,6 +31,7 @@ function noop() {} const DefaultDispatcher: HostDispatcher = { f /* flushSyncWork */: noop, + r /* requestFormReset */: noop, D /* prefetchDNS */: noop, C /* preconnect */: noop, L /* preload */: noop, diff --git a/packages/react-dom/src/ReactDOMSharedInternalsFB.js b/packages/react-dom/src/ReactDOMSharedInternalsFB.js index 7bd7a1ab8ae2b..4e425d5ddca79 100644 --- a/packages/react-dom/src/ReactDOMSharedInternalsFB.js +++ b/packages/react-dom/src/ReactDOMSharedInternalsFB.js @@ -27,6 +27,7 @@ function noop() {} const DefaultDispatcher: HostDispatcher = { f /* flushSyncWork */: noop, + r /* requestFormReset */: noop, D /* prefetchDNS */: noop, C /* preconnect */: noop, L /* preload */: noop, diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 86979fa11f81d..61660e9843369 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -48,6 +48,7 @@ export { export { useFormStatus, useFormState, + requestFormReset, } from 'react-dom-bindings/src/shared/ReactDOMFormActions'; if (__DEV__) { diff --git a/packages/react-dom/src/client/ReactDOMFB.js b/packages/react-dom/src/client/ReactDOMFB.js index e24cba3a52b46..9b016b04d8dfd 100644 --- a/packages/react-dom/src/client/ReactDOMFB.js +++ b/packages/react-dom/src/client/ReactDOMFB.js @@ -48,6 +48,7 @@ export { export { useFormStatus, useFormState, + requestFormReset, } from 'react-dom-bindings/src/shared/ReactDOMFormActions'; if (__DEV__) { diff --git a/packages/react-dom/src/shared/ReactDOMTypes.js b/packages/react-dom/src/shared/ReactDOMTypes.js index 2da68cae2d3f3..dbfe07f9ec8f3 100644 --- a/packages/react-dom/src/shared/ReactDOMTypes.js +++ b/packages/react-dom/src/shared/ReactDOMTypes.js @@ -83,6 +83,7 @@ export type PreinitModuleScriptOptions = { export type HostDispatcher = { f /* flushSyncWork */: () => boolean | void, + r /* requestFormReset */: (form: HTMLFormElement) => void, D /* prefetchDNS */: (href: string) => void, C /* preconnect */: (href: string, crossOrigin?: ?CrossOriginEnum) => void, L /* preload */: ( diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index b32c9c120166d..c712eb6c387d8 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -3008,13 +3008,18 @@ export function startHostTransition( // once more of this function is implemented. () => { // Automatically reset the form when the action completes. - requestFormReset(formFiber); + requestFormResetImpl(formFiber); return callback(formData); }, ); } -function requestFormReset(formFiber: Fiber) { +export function requestFormReset(formFiber: Fiber) { + // TODO: Not yet implemented. Need to upgrade the fiber to be stateful + // before scheduling the form reset. +} + +function requestFormResetImpl(formFiber: Fiber) { const transition = requestCurrentTransition(); if (__DEV__) {