Skip to content

Commit

Permalink
ReactDOM.requestFormReset
Browse files Browse the repository at this point in the history
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 facebook#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));
  })
}
```
  • Loading branch information
acdlite committed Apr 10, 2024
1 parent f96f89f commit 696f334
Show file tree
Hide file tree
Showing 5 changed files with 443 additions and 78 deletions.
14 changes: 10 additions & 4 deletions packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -1954,13 +1954,19 @@ function flushSyncWork() {
}

function requestFormReset(form: HTMLFormElement) {
previousDispatcher.r(/* requestFormReset */ form);
const formInst = getInstanceFromNodeDOMTree(form);
if (formInst !== null) {
if (
formInst !== null &&
formInst.tag === HostComponent &&
formInst.type === 'form'
) {
requestFormResetOnFiber(formInst);
} else {
// TODO: What if none of the dispatchers find a matching form instance?
// Should we detect this in dev and warn?
// This form was either not rendered by this React renderer (or it's an
// invalid type). Try the next one.
//
// The last implementation in the sequence will throw an error.
previousDispatcher.r(/* requestFormReset */ form);
}
}

Expand Down
9 changes: 8 additions & 1 deletion packages/react-dom/src/ReactDOMSharedInternals.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,16 @@ export type ReactDOMInternalsDev = ReactDOMInternals & {

function noop() {}

function requestFormReset(element: HTMLFormElement) {
throw new Error(
'Invalid form element. requestFormReset must be passed a form that was ' +
'rendered by React.',
);
}

const DefaultDispatcher: HostDispatcher = {
f /* flushSyncWork */: noop,
r /* requestFormReset */: noop,
r /* requestFormReset */: requestFormReset,
D /* prefetchDNS */: noop,
C /* preconnect */: noop,
L /* preload */: noop,
Expand Down
Loading

0 comments on commit 696f334

Please sign in to comment.