@@ -524,6 +524,7 @@ describe('ReactDOMFizzForm', () => {
524524
525525 // @gate enableFormActions
526526 it ( 'can provide a custom action on buttons the server for actions' , async ( ) => {
527+ const hiddenRef = React . createRef ( ) ;
527528 const inputRef = React . createRef ( ) ;
528529 const buttonRef = React . createRef ( ) ;
529530 let foo ;
@@ -546,7 +547,7 @@ describe('ReactDOMFizzForm', () => {
546547 function App ( ) {
547548 return (
548549 < form >
549- < input type = "hidden" name = "foo" value = "bar" />
550+ < input type = "hidden" name = "foo" value = "bar" ref = { hiddenRef } />
550551 < input
551552 type = "submit"
552553 formAction = { action }
@@ -588,6 +589,8 @@ describe('ReactDOMFizzForm', () => {
588589 ReactDOMClient . hydrateRoot ( container , < App /> ) ;
589590 } ) ;
590591
592+ expect ( hiddenRef . current . name ) . toBe ( 'foo' ) ;
593+
591594 submit ( inputRef . current ) ;
592595
593596 expect ( foo ) . toBe ( 'bar' ) ;
@@ -598,4 +601,53 @@ describe('ReactDOMFizzForm', () => {
598601
599602 expect ( foo ) . toBe ( 'bar' ) ;
600603 } ) ;
604+
605+ // @gate enableFormActions
606+ it ( 'can hydrate hidden fields in the beginning of a form' , async ( ) => {
607+ const hiddenRef = React . createRef ( ) ;
608+
609+ let invoked = false ;
610+ function action ( formData ) {
611+ invoked = true ;
612+ }
613+ action . $$FORM_ACTION = function ( identifierPrefix ) {
614+ const extraFields = new FormData ( ) ;
615+ extraFields . append ( identifierPrefix + 'hello' , 'world' ) ;
616+ return {
617+ action : '' ,
618+ name : identifierPrefix ,
619+ method : 'POST' ,
620+ encType : 'multipart/form-data' ,
621+ data : extraFields ,
622+ } ;
623+ } ;
624+ function App ( ) {
625+ return (
626+ < form action = { action } >
627+ < input type = "hidden" name = "bar" defaultValue = "baz" ref = { hiddenRef } />
628+ < input type = "text" name = "foo" defaultValue = "bar" />
629+ </ form >
630+ ) ;
631+ }
632+
633+ const stream = await ReactDOMServer . renderToReadableStream ( < App /> ) ;
634+ await readIntoContainer ( stream ) ;
635+
636+ const barField = container . querySelector ( '[name=bar]' ) ;
637+
638+ await act ( async ( ) => {
639+ ReactDOMClient . hydrateRoot ( container , < App /> ) ;
640+ } ) ;
641+
642+ expect ( hiddenRef . current ) . toBe ( barField ) ;
643+
644+ expect ( hiddenRef . current . name ) . toBe ( 'bar' ) ;
645+ expect ( hiddenRef . current . value ) . toBe ( 'baz' ) ;
646+
647+ expect ( container . querySelectorAll ( '[name=bar]' ) . length ) . toBe ( 1 ) ;
648+
649+ submit ( hiddenRef . current . form ) ;
650+
651+ expect ( invoked ) . toBe ( true ) ;
652+ } ) ;
601653} ) ;
0 commit comments