React.js: submit form programmatically does not trigger onSubmit event

泄露秘密 提交于 2019-12-05 12:24:00

问题


I want to submit a React form after a click on a link.

To do so I need to submit the form programmatically if the link is clicked.

my problem is : onSubmit handler is not being fired after the form submit .

Here is a code snipped that I made for this purpose:

var MyForm = React.createClass({
  handleSubmit: function(e){
    console.log('Form submited');
     e.preventDefault();
  },
  submitForm : function(e){
    this.refs.formToSubmit.submit();
  },
  render: function() {
    return (
    <form ref="formToSubmit" onSubmit={this.handleSubmit}>
    <input name='myInput'/>
    <a onClick={this.submitForm}>Validate</a>
    </form>);
  }
});

ReactDOM.render(
  <MyForm name="World" />,
  document.getElementById('container')
);

The handleSubmit is not invoked and the default behavior is executed (the form being submitted). Is this a ReactJs bug or a normal behavior? Is there a way to get the onSubmit handler invoked ?


回答1:


I have success with this. This triggers the handleSubmit upon clicking. Hope this helps.

<form onSubmit={this.handleSubmit} ref={el => this.form = el}>
    <a onClick={() => { this.form.dispatch(new Event('submit'))}}>Validate</a>
</form>

Found from here: https://github.com/facebook/react/issues/6796




回答2:


Your current onSubmit is bound to the triggering of a React SyntheticEvent and not the native form submit event. That explains why this.refs.formToSubmit.submit(); is not triggering your handler. As far as I know, trying to manually trigger that SyntheticEvent is not a recommended or worthwhile pursuit.

I believe the idiomatic way to accomplish this is to structure the JSX/HTML to use a <button> or <input> of type submit. Either of those will trigger your handleSubmit handler. In my opinion, it will reduce complexity, consolidate your handlers, and seems to be your best solution.

e.g.

  • <input type="submit" value="Validate" />
  • <button type="submit">Validate</button>



回答3:


I had this same issue but couldn't fix it. No matter what I did, doing document.querySelector('form').submit() would not trigger the onSubmit handler. I tried including an invisible <input type="submit">, but still .submit() would not trigger it. So I just changed to keeping the invisible submit (style="display:none") and then doing .click() on that invisible submit button, surprisingly it works even with display:none. I tested only in Firefox though.




回答4:


You shouldn't expect a form ref to attach an additional callback to submit for you by default. This would be bad design of the framework when working with programmatically set things such as DOM element refs.

You should use the ref to instantiate all of the events you need in any order you want instead of relying on an untold internal implementation of a ref [when instantiated by a form element].

This works:

this.refs.formToSubmit.onSubmit();
this.refs.formToSubmit.submit();

Actual submit should always occur last.




回答5:


This has nothing to do with React. It's a "feature" of the DOM API: .submit() method does not actually fire submit event, and it doesn't trigger input validations either. See http://codetheory.in/javascript-fire-onsubmit-by-calling-form-submit/.

Possible workaround is, as suggested, create a submit button, and programmatically call .click() on it. Or, you could programmatically create a submit event with new Event() and dispatch it using .dispatchEvent(). However, new Event() is not available in IE.




回答6:


You should be using input tag with type submit instead of anchor tag, Since anchor tag does not trigger an submit event.

render: function() {
  return (
    <form ref="formToSubmit" onSubmit={this.handleSubmit}>
       <input name='myInput'/>
       <input onClick={this.submitForm} type="submit" value="Validate" />
    </form>
  );
}


来源:https://stackoverflow.com/questions/37901223/react-js-submit-form-programmatically-does-not-trigger-onsubmit-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!