ReactDOM: Fix missing form data when the submitter is outside the form (#28056)
Juan Pinilla committed
May 2, 2024 at 06:06 UTC
29d3c83f0a84354b18ab3f064f2d43a4c116d6ed
2 files changed
+29
-7
packages/react-dom-bindings/src/events/plugins/FormActionEventPlugin.js
+3
@@ -92,6 +92,9 @@ function extractEvents(
92
const temp = submitter.ownerDocument.createElement('input');
93
temp.name = submitter.name;
94
temp.value = submitter.value;
95
+ if (form.id) {
96
+ temp.setAttribute('form', form.id);
97
+ }
98
(submitter.parentNode: any).insertBefore(temp, submitter);
99
formData = new FormData(form);
100
(temp.parentNode: any).removeChild(temp);
packages/react-dom/src/__tests__/ReactDOMForm-test.js
+26
-7
@@ -481,6 +481,7 @@ describe('ReactDOMForm', () => {
481
it('can read the clicked button in the formdata event', async () => {
482
const inputRef = React.createRef();
483
const buttonRef = React.createRef();
484
+ const outsideButtonRef = React.createRef();
485
let button;
486
let title;
487
@@ -492,14 +493,27 @@ describe('ReactDOMForm', () => {
493
const root = ReactDOMClient.createRoot(container);
494
await act(async () => {
495
root.render(
495
- <form action={action}>
496
- <input type="text" name="title" defaultValue="hello" />
497
- <input type="submit" name="button" value="save" />
498
- <input type="submit" name="button" value="delete" ref={inputRef} />
499
- <button name="button" value="edit" ref={buttonRef}>
500
- Edit
496
+ <>
497
+ <form action={action}>
498
+ <input type="text" name="title" defaultValue="hello" />
499
+ <input type="submit" name="button" value="save" />
500
+ <input type="submit" name="button" value="delete" ref={inputRef} />
501
+ <button name="button" value="edit" ref={buttonRef}>
502
+ Edit
503
+ </button>
504
+ </form>
505
+ <form id="form" action={action}>
506
+ <input type="text" name="title" defaultValue="hello" />
507
+ </form>
508
+ <button
509
+ form="form"
510
+ name="button"
511
+ value="outside"
512
+ ref={outsideButtonRef}>
513
+ Button outside form
514
</button>
502
- </form>,
515
+ ,
516
+ </>,
517
);
518
});
519
@@ -520,6 +534,11 @@ describe('ReactDOMForm', () => {
534
expect(button).toBe('edit');
535
expect(title).toBe('hello');
536
537
+ await submit(outsideButtonRef.current);
538
+
539
+ expect(button).toBe('outside');
540
+ expect(title).toBe('hello');
541
+
542
// Ensure that the type field got correctly restored
543
expect(inputRef.current.getAttribute('type')).toBe('submit');
544
expect(buttonRef.current.getAttribute('type')).toBe(null);