Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 88d44a2

Browse files
acdlitekassens
authored andcommitted
Rethrow errors from form actions (#26689)
This is the next step toward full support for async form actions. Errors thrown inside form actions should cause the form to re-render and throw the error so it can be captured by an error boundary. The behavior is the same if the `<form />` had an internal useTransition hook, which is pretty much exactly how we implement it, too. The first time an action is called, the form's HostComponent is "upgraded" to become stateful, by lazily mounting a list of hooks. The rest of the implementation for function components can be shared. Because the error handling behavior added in this commit is just using useTransition under-the-hood, it also handles pending states, too. However, this pending state can't be observed until we add a new hook for that purpose. I'll add this next.
1 parent 00f97f7 commit 88d44a2

File tree

7 files changed

+521
-35
lines changed

7 files changed

+521
-35
lines changed

packages/react-dom-bindings/src/events/plugins/FormActionEventPlugin.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {EventSystemFlags} from '../EventSystemFlags';
1414
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
1515

1616
import {getFiberCurrentPropsFromNode} from '../../client/ReactDOMComponentTree';
17+
import {startHostTransition} from 'react-reconciler/src/ReactFiberReconciler';
1718

1819
import {SyntheticEvent} from '../SyntheticEvent';
1920

@@ -24,7 +25,7 @@ import {SyntheticEvent} from '../SyntheticEvent';
2425
function extractEvents(
2526
dispatchQueue: DispatchQueue,
2627
domEventName: DOMEventName,
27-
targetInst: null | Fiber,
28+
maybeTargetInst: null | Fiber,
2829
nativeEvent: AnyNativeEvent,
2930
nativeEventTarget: null | EventTarget,
3031
eventSystemFlags: EventSystemFlags,
@@ -33,11 +34,12 @@ function extractEvents(
3334
if (domEventName !== 'submit') {
3435
return;
3536
}
36-
if (!targetInst || targetInst.stateNode !== nativeEventTarget) {
37+
if (!maybeTargetInst || maybeTargetInst.stateNode !== nativeEventTarget) {
3738
// If we're inside a parent root that itself is a parent of this root, then
3839
// its deepest target won't be the actual form that's being submitted.
3940
return;
4041
}
42+
const formInst = maybeTargetInst;
4143
const form: HTMLFormElement = (nativeEventTarget: any);
4244
let action = (getFiberCurrentPropsFromNode(form): any).action;
4345
const submitter: null | HTMLInputElement | HTMLButtonElement =
@@ -94,8 +96,8 @@ function extractEvents(
9496
} else {
9597
formData = new FormData(form);
9698
}
97-
// TODO: Deal with errors and pending state.
98-
action(formData);
99+
100+
startHostTransition(formInst, action, formData);
99101
}
100102

101103
dispatchQueue.push({

0 commit comments

Comments
 (0)