Skip to content

Commit e45e8f3

Browse files
committed
ReactDOM.requestFormReset (#28809)
Based on: - #28808 - #28804 --- This adds a React DOM method called requestFormReset that schedules a form reset to occur when the current transition completes. Internally, it's the same method that's called automatically whenever a form action is submitted. It only affects uncontrolled form inputs. See #28804 for details. The reason for the public API is so UI libraries can implement their own action-based APIs and maintain the form-resetting behavior, something like this: ```js function onSubmit(event) { // Disable default form submission behavior event.preventDefault(); const form = event.target; startTransition(async () => { // Request the form to reset once the action // has completed requestFormReset(form); // Call the user-provided action prop await action(new FormData(form)); }) } ``` DiffTrain build for [da69b6a](da69b6a)
1 parent 52ba1cb commit e45e8f3

11 files changed

+1661
-1599
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
374b5d26c2a379fe87ee6817217c8956c4e39aac
1+
da69b6af9697b8042834644b14d0e715d4ace18a

compiled/facebook-www/ReactDOM-dev.classic.js

Lines changed: 75 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -2747,7 +2747,7 @@ if (__DEV__) {
27472747
return dispatcher.useFormState(action, initialState, permalink);
27482748
}
27492749
}
2750-
function requestFormReset$1(form) {
2750+
function requestFormReset$2(form) {
27512751
Internals.d
27522752
/* ReactDOMCurrentDispatcher */
27532753
.r(
@@ -15848,68 +15848,8 @@ if (__DEV__) {
1584815848
);
1584915849
}
1585015850

15851-
var queue;
15852-
15853-
if (formFiber.memoizedState === null) {
15854-
// Upgrade this host component fiber to be stateful. We're going to pretend
15855-
// it was stateful all along so we can reuse most of the implementation
15856-
// for function components and useTransition.
15857-
//
15858-
// Create the state hook used by TransitionAwareHostComponent. This is
15859-
// essentially an inlined version of mountState.
15860-
var newQueue = {
15861-
pending: null,
15862-
lanes: NoLanes,
15863-
// We're going to cheat and intentionally not create a bound dispatch
15864-
// method, because we can call it directly in startTransition.
15865-
dispatch: null,
15866-
lastRenderedReducer: basicStateReducer,
15867-
lastRenderedState: NotPendingTransition
15868-
};
15869-
queue = newQueue;
15870-
var stateHook = {
15871-
memoizedState: NotPendingTransition,
15872-
baseState: NotPendingTransition,
15873-
baseQueue: null,
15874-
queue: newQueue,
15875-
next: null
15876-
}; // We use another state hook to track whether the form needs to be reset.
15877-
// The state is an empty object. To trigger a reset, we update the state
15878-
// to a new object. Then during rendering, we detect that the state has
15879-
// changed and schedule a commit effect.
15880-
15881-
var initialResetState = {};
15882-
var newResetStateQueue = {
15883-
pending: null,
15884-
lanes: NoLanes,
15885-
// We're going to cheat and intentionally not create a bound dispatch
15886-
// method, because we can call it directly in startTransition.
15887-
dispatch: null,
15888-
lastRenderedReducer: basicStateReducer,
15889-
lastRenderedState: initialResetState
15890-
};
15891-
var resetStateHook = {
15892-
memoizedState: initialResetState,
15893-
baseState: initialResetState,
15894-
baseQueue: null,
15895-
queue: newResetStateQueue,
15896-
next: null
15897-
};
15898-
stateHook.next = resetStateHook; // Add the hook list to both fiber alternates. The idea is that the fiber
15899-
// had this hook all along.
15900-
15901-
formFiber.memoizedState = stateHook;
15902-
var alternate = formFiber.alternate;
15903-
15904-
if (alternate !== null) {
15905-
alternate.memoizedState = stateHook;
15906-
}
15907-
} else {
15908-
// This fiber was already upgraded to be stateful.
15909-
var _stateHook = formFiber.memoizedState;
15910-
queue = _stateHook.queue;
15911-
}
15912-
15851+
var stateHook = ensureFormComponentIsStateful(formFiber);
15852+
var queue = stateHook.queue;
1591315853
startTransition(
1591415854
formFiber,
1591515855
queue,
@@ -15918,13 +15858,76 @@ if (__DEV__) {
1591815858
// once more of this function is implemented.
1591915859
function () {
1592015860
// Automatically reset the form when the action completes.
15921-
requestFormResetImpl(formFiber);
15861+
requestFormReset$1(formFiber);
1592215862
return callback(formData);
1592315863
}
1592415864
);
1592515865
}
1592615866

15927-
function requestFormResetImpl(formFiber) {
15867+
function ensureFormComponentIsStateful(formFiber) {
15868+
var existingStateHook = formFiber.memoizedState;
15869+
15870+
if (existingStateHook !== null) {
15871+
// This fiber was already upgraded to be stateful.
15872+
return existingStateHook;
15873+
} // Upgrade this host component fiber to be stateful. We're going to pretend
15874+
// it was stateful all along so we can reuse most of the implementation
15875+
// for function components and useTransition.
15876+
//
15877+
// Create the state hook used by TransitionAwareHostComponent. This is
15878+
// essentially an inlined version of mountState.
15879+
15880+
var newQueue = {
15881+
pending: null,
15882+
lanes: NoLanes,
15883+
// We're going to cheat and intentionally not create a bound dispatch
15884+
// method, because we can call it directly in startTransition.
15885+
dispatch: null,
15886+
lastRenderedReducer: basicStateReducer,
15887+
lastRenderedState: NotPendingTransition
15888+
};
15889+
var stateHook = {
15890+
memoizedState: NotPendingTransition,
15891+
baseState: NotPendingTransition,
15892+
baseQueue: null,
15893+
queue: newQueue,
15894+
next: null
15895+
}; // We use another state hook to track whether the form needs to be reset.
15896+
// The state is an empty object. To trigger a reset, we update the state
15897+
// to a new object. Then during rendering, we detect that the state has
15898+
// changed and schedule a commit effect.
15899+
15900+
var initialResetState = {};
15901+
var newResetStateQueue = {
15902+
pending: null,
15903+
lanes: NoLanes,
15904+
// We're going to cheat and intentionally not create a bound dispatch
15905+
// method, because we can call it directly in startTransition.
15906+
dispatch: null,
15907+
lastRenderedReducer: basicStateReducer,
15908+
lastRenderedState: initialResetState
15909+
};
15910+
var resetStateHook = {
15911+
memoizedState: initialResetState,
15912+
baseState: initialResetState,
15913+
baseQueue: null,
15914+
queue: newResetStateQueue,
15915+
next: null
15916+
};
15917+
stateHook.next = resetStateHook; // Add the hook list to both fiber alternates. The idea is that the fiber
15918+
// had this hook all along.
15919+
15920+
formFiber.memoizedState = stateHook;
15921+
var alternate = formFiber.alternate;
15922+
15923+
if (alternate !== null) {
15924+
alternate.memoizedState = stateHook;
15925+
}
15926+
15927+
return stateHook;
15928+
}
15929+
15930+
function requestFormReset$1(formFiber) {
1592815931
var transition = requestCurrentTransition();
1592915932

1593015933
{
@@ -15945,8 +15948,9 @@ if (__DEV__) {
1594515948
}
1594615949
}
1594715950

15951+
var stateHook = ensureFormComponentIsStateful(formFiber);
1594815952
var newResetState = {};
15949-
var resetStateHook = formFiber.memoizedState.next;
15953+
var resetStateHook = stateHook.next;
1595015954
var resetStateQueue = resetStateHook.queue;
1595115955
dispatchSetState(formFiber, resetStateQueue, newResetState);
1595215956
}
@@ -36226,7 +36230,7 @@ if (__DEV__) {
3622636230
return root;
3622736231
}
3622836232

36229-
var ReactVersion = "19.0.0-www-classic-c937066f";
36233+
var ReactVersion = "19.0.0-www-classic-3b25da96";
3623036234

3623136235
function createPortal$1(
3623236236
children,
@@ -45708,8 +45712,9 @@ if (__DEV__) {
4570845712
formInst !== null &&
4570945713
formInst.tag === HostComponent &&
4571045714
formInst.type === "form"
45711-
);
45712-
else {
45715+
) {
45716+
requestFormReset$1(formInst);
45717+
} else {
4571345718
// This form was either not rendered by this React renderer (or it's an
4571445719
// invalid type). Try the next one.
4571545720
//
@@ -49788,7 +49793,7 @@ if (__DEV__) {
4978849793
exports.preload = preload;
4978949794
exports.preloadModule = preloadModule;
4979049795
exports.render = render;
49791-
exports.requestFormReset = requestFormReset$1;
49796+
exports.requestFormReset = requestFormReset$2;
4979249797
exports.unmountComponentAtNode = unmountComponentAtNode;
4979349798
exports.unstable_batchedUpdates = batchedUpdates$1;
4979449799
exports.unstable_createEventHandle = createEventHandle;

0 commit comments

Comments
 (0)