Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Ref Form onSubmit Handler not triggered

I have a form.

I try to submit this form from a different function.

To do so I created a ref. This ref, when printed, has the correct HTML Node and this node also has an submit method. When this submit method is called (formNode.submit()) the form get's submitted, but the onSubmit handler is never triggered.

Why?

Here is a simplified example which shows the same behavior.

class Form extends React.Component {
  constructor() {
    super();

    this.form = React.createRef();
  }

  render() {
    return (
      <div onClick={() => this.form.submit()}>
        Click me!
        <form
          onSubmit={e => console.log(e)}
          ref={f => (this.form = f)}
        />
      </div>
    );
  }
}

https://codesandbox.io/s/vm8pkmony

like image 721
SlootSantos Avatar asked Jun 25 '18 15:06

SlootSantos


4 Answers

Starting from React 17 you have to add cancelable and bubbles properties to your event. Otherwise, the solution from the accepted answer won't work. It's caused by some changes in event delegation.

this.form.dispatchEvent(
    new Event("submit", { cancelable: true, bubbles: true })
);
like image 177
Karol Dabrowski Avatar answered Oct 17 '22 03:10

Karol Dabrowski


For your specific use case, you'll have to fire the submit event of the form using dispatchEvent.

this.form.dispatchEvent(new Event("submit"));
like image 45
br0k3n c0d3 Avatar answered Oct 17 '22 01:10

br0k3n c0d3


It's an old question but we can do something like this;

As Ramon Balthazar mentioned above;

When you call the form's submit function, the submit event is not fired.

To solve this problem, we can create hidden button and add reference to it, than we can click that button with ref, it will submit the form and trigger submit event;

import { useRef } from 'react'

export default function Form(props) {
    const hiddenButtonRef = useRef(null)

    return (
        <>
            <form onSubmit={(e) => console.log(e)}>
                <input type="submit" style={{ display: 'none' }} ref={hiddenButtonRef} />
            </form>

            <div onClick={() => hiddenButtonRef.current.click()}>Click me!</div>
        </>
    )
}
like image 42
Closery Avatar answered Oct 17 '22 02:10

Closery


When you call the form's submit function, the submit event is not fired.

This behaviour is intended because we're assuming that if you called submit directly you already validated your form.

like image 2
Ramon Balthazar Avatar answered Oct 17 '22 01:10

Ramon Balthazar