@@ -1670,6 +1670,48 @@ describe('ReactDOMForm', () => {
16701670 expect ( divRef . current . textContent ) . toEqual ( 'Current username: acdlite' ) ;
16711671 } ) ;
16721672
1673+ it . only ( 'multiple form submissions in rapid succession do not throw' , async ( ) => {
1674+ const submitFormTwiceButtonRef = React . createRef ( ) ;
1675+ let actionCounter = 0 ;
1676+ function App ( ) {
1677+ const formRef = React . createRef ( ) ;
1678+ // Submits the form twice in quick succession
1679+ // This simulates a user clicking a button twice in rapid succession
1680+ async function submitFormTwice ( ) {
1681+ formRef . current . requestSubmit ( ) ;
1682+ await new Promise ( res => setTimeout ( res , 1 ) ) ;
1683+ formRef . current . requestSubmit ( ) ;
1684+ }
1685+
1686+ // This is a userspace action. it must take a non-zero amount of time to
1687+ // allow the form to be submitted again before the first one finishes.
1688+ // Otherwise, the form transitions will be batched and will not run concurrently.
1689+ async function submitForm ( ) {
1690+ actionCounter ++ ;
1691+ return new Promise ( res => setTimeout ( res , 1 ) ) ;
1692+ }
1693+
1694+ return (
1695+ < >
1696+ < form ref = { formRef } action = { submitForm } >
1697+ < button type = "submit" > Submit</ button >
1698+ </ form >
1699+ < button ref = { submitFormTwiceButtonRef } onClick = { submitFormTwice } >
1700+ Submit twice
1701+ </ button >
1702+ </ >
1703+ ) ;
1704+ }
1705+
1706+ const root = ReactDOMClient . createRoot ( container ) ;
1707+ await act ( ( ) => root . render ( < App /> ) ) ;
1708+
1709+ await act ( async ( ) => {
1710+ submitFormTwiceButtonRef . current . click ( ) ;
1711+ } ) ;
1712+ expect ( actionCounter ) . toBe ( 2 ) ;
1713+ } ) ;
1714+
16731715 it (
16741716 'requestFormReset works with inputs that are not descendants ' +
16751717 'of the form element' ,
0 commit comments