@@ -518,6 +518,14 @@ if (__DEV__) {
518518 Form . displayName = "Form" ;
519519}
520520
521+ type HTMLSubmitEvent = React . BaseSyntheticEvent <
522+ SubmitEvent ,
523+ Event ,
524+ HTMLFormElement
525+ > ;
526+
527+ type HTMLFormSubmitter = HTMLButtonElement | HTMLInputElement ;
528+
521529interface FormImplProps extends FormProps {
522530 fetcherKey ?: string ;
523531}
@@ -539,66 +547,20 @@ const FormImpl = React.forwardRef<HTMLFormElement, FormImplProps>(
539547 let formMethod : FormMethod =
540548 method . toLowerCase ( ) === "get" ? "get" : "post" ;
541549 let formAction = useFormAction ( action ) ;
542- let formRef = React . useRef < HTMLFormElement > ( ) ;
543- let ref = useComposedRefs ( forwardedRef , formRef ) ;
544-
545- // When calling `submit` on the form element itself, we don't get data from
546- // the button that submitted the event. For example:
547- //
548- // <Form>
549- // <button name="something" value="whatever">Submit</button>
550- // </Form>
551- //
552- // formData.get("something") should be "whatever", but we don't get that
553- // unless we call submit on the clicked button itself.
554- //
555- // To figure out which button triggered the submit, we'll attach a click
556- // event listener to the form. The click event is always triggered before
557- // the submit event (even when submitting via keyboard when focused on
558- // another form field, yeeeeet) so we should have access to that button's
559- // data for use in the submit handler.
560- let clickedButtonRef = React . useRef < any > ( ) ;
561-
562- React . useEffect ( ( ) => {
563- let form = formRef . current ;
564- if ( ! form ) return ;
565-
566- function handleClick ( event : MouseEvent ) {
567- if ( ! ( event . target instanceof Element ) ) return ;
568- let submitButton = event . target . closest <
569- HTMLButtonElement | HTMLInputElement
570- > ( "button,input[type=submit]" ) ;
571-
572- if (
573- submitButton &&
574- submitButton . form === form &&
575- submitButton . type === "submit"
576- ) {
577- clickedButtonRef . current = submitButton ;
578- }
579- }
580-
581- window . addEventListener ( "click" , handleClick ) ;
582- return ( ) => {
583- window . removeEventListener ( "click" , handleClick ) ;
584- } ;
585- } , [ ] ) ;
586-
587550 let submitHandler : React . FormEventHandler < HTMLFormElement > = ( event ) => {
588551 onSubmit && onSubmit ( event ) ;
589552 if ( event . defaultPrevented ) return ;
590553 event . preventDefault ( ) ;
591554
592- submit ( clickedButtonRef . current || event . currentTarget , {
593- method,
594- replace,
595- } ) ;
596- clickedButtonRef . current = null ;
555+ let submitter = ( event as unknown as HTMLSubmitEvent ) . nativeEvent
556+ . submitter as HTMLFormSubmitter | null ;
557+
558+ submit ( submitter || event . currentTarget , { method, replace } ) ;
597559 } ;
598560
599561 return (
600562 < form
601- ref = { ref }
563+ ref = { forwardedRef }
602564 method = { formMethod }
603565 action = { formAction }
604566 encType = { encType }
@@ -823,24 +785,6 @@ export function useFormAction(action = "."): string {
823785 return pathname + search ;
824786}
825787
826- function useComposedRefs < RefValueType = any > (
827- ...refs : Array < React . Ref < RefValueType > | null | undefined >
828- ) : React . RefCallback < RefValueType > {
829- return React . useCallback ( ( node ) => {
830- for ( let ref of refs ) {
831- if ( ref == null ) continue ;
832- if ( typeof ref === "function" ) {
833- ref ( node ) ;
834- } else {
835- try {
836- ( ref as React . MutableRefObject < RefValueType > ) . current = node ! ;
837- } catch ( _ ) { }
838- }
839- }
840- // eslint-disable-next-line react-hooks/exhaustive-deps
841- } , refs ) ;
842- }
843-
844788function createFetcherForm ( fetcherKey : string ) {
845789 let FetcherForm = React . forwardRef < HTMLFormElement , FormProps > (
846790 ( props , ref ) => {
0 commit comments