diff --git a/packages/react-dom-bindings/src/events/plugins/FormActionEventPlugin.js b/packages/react-dom-bindings/src/events/plugins/FormActionEventPlugin.js index d862ae678f38b..7f2fa5a4f5404 100644 --- a/packages/react-dom-bindings/src/events/plugins/FormActionEventPlugin.js +++ b/packages/react-dom-bindings/src/events/plugins/FormActionEventPlugin.js @@ -92,6 +92,10 @@ function extractEvents( const temp = submitter.ownerDocument.createElement('input'); temp.name = submitter.name; temp.value = submitter.value; + const isOutsideForm = !form.contains(submitter); + if (isOutsideForm) { + temp.setAttribute('form', form.id); + } (submitter.parentNode: any).insertBefore(temp, submitter); formData = new FormData(form); (temp.parentNode: any).removeChild(temp); diff --git a/packages/react-dom/src/__tests__/ReactDOMForm-test.js b/packages/react-dom/src/__tests__/ReactDOMForm-test.js index 123619d2908c9..f37f1f5c3c2a2 100644 --- a/packages/react-dom/src/__tests__/ReactDOMForm-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMForm-test.js @@ -481,6 +481,7 @@ describe('ReactDOMForm', () => { it('can read the clicked button in the formdata event', async () => { const inputRef = React.createRef(); const buttonRef = React.createRef(); + const outsideButtonRef = React.createRef(); let button; let title; @@ -492,14 +493,24 @@ describe('ReactDOMForm', () => { const root = ReactDOMClient.createRoot(container); await act(async () => { root.render( -
- - - - -
, +
+ + + + +
+ , + , ); }); @@ -520,6 +531,11 @@ describe('ReactDOMForm', () => { expect(button).toBe('edit'); expect(title).toBe('hello'); + await submit(outsideButtonRef.current); + + expect(button).toBe('outside'); + expect(title).toBe('hello'); + // Ensure that the type field got correctly restored expect(inputRef.current.getAttribute('type')).toBe('submit'); expect(buttonRef.current.getAttribute('type')).toBe(null);