116

I've been experimenting with React. In my experiement, I'm using the Reactstrap framework.When I click a button, I've noticed that the HTML form submits. Is there a way to prevent form submission when a button is clicked?

I've recreated my issue here. My form is pretty basic and looks like this:

<Form>
  <h3>Buttons</h3> 
  <p>
    <Button color="primary" onClick={this.onTestClick}>primary</Button>&nbsp;
  </p>
</Form>

What am I missing?

Some User
  • 5,257
  • 13
  • 51
  • 93
  • 4
    Seems related to [this](http://stackoverflow.com/questions/9824808/disable-form-auto-submit-on-button-click). Tried setting the button's type to [button](http://jsbin.com/xatuha/edit?html,js,output)? – Diego Zacarias Oct 01 '16 at 18:14

14 Answers14

131

I think it's first worth noting that without javascript (plain html), the form element submits when clicking either the <input type="submit" value="submit form"> or <button>submits form too</button>. In javascript you can prevent that by using an event handler and calling e.preventDefault() on button click, or form submit. e is the event object passed into the event handler. With react, the two relevant event handlers are available via the form as onSubmit, and the other on the button via onClick.

Example: http://jsbin.com/vowuley/edit?html,js,console,output

eddywashere
  • 2,548
  • 2
  • 18
  • 15
94

No JS needed really ... Just add a type attribute to the button with a value of button

<Button type="button" color="primary" onClick={this.onTestClick}>primary</Button>&nbsp;

By default, button elements are of the type "submit" which causes them to submit their enclosing form element (if any). Changing the type to "button" prevents that.

HaukurHaf
  • 13,522
  • 5
  • 44
  • 59
  • 68
    if you are using a form, doing this won't allow the users to submit the form pressing the enter key, which in my opinion is a big deal. – VdeVentura Sep 04 '17 at 00:07
  • 1
    Thanks for a great answer. FYI, here is a reference about the default behavior mentioned here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type – Mike Moore Jun 12 '19 at 21:00
  • @StormRage, do you know how to handle events where you'd like the form to work using the enter key (i.e. not using onClick on the submit button), but would still like to disable the submit button based on state validation (password length for example) – nkhil Dec 28 '19 at 01:45
  • Best use is to use JS since it's JS and to cover all scenarios. – Chizl Jan 03 '20 at 16:59
40

preventDefault is what you're looking for. To just block the button from submitting

<Button onClick={this.onClickButton} ...

code

onClickButton (event) {
  event.preventDefault();
}

If you have a form which you want to handle in a custom way you can capture a higher level event onSubmit which will also stop that button from submitting.

<form onSubmit={this.onSubmit}>

and above in code

onSubmit (event) {
  event.preventDefault();

  // custom form handling here
}
Pawel
  • 16,093
  • 5
  • 70
  • 73
  • 4
    Thanks! `
    { e.preventDefault(); }} >` allowed me to have a submit button on a form, but not have a page refresh when form was submitted.
    – Shiraz Mar 19 '19 at 13:28
  • Is there a shortcut, like `@submit.prevent` in Vue? – vsp Sep 17 '22 at 17:27
21

Make sure you put the onSubmit attribute on the form not the button in case you have a from.

<form onSubmit={e => e.preventDefault()}>
    <button onClick={this.handleClick}>Click Me</button>
</form>

Make sure to change the button onClick attribute to your custom function.

Community
  • 1
  • 1
Yonatan Dawit
  • 589
  • 7
  • 11
  • 1
    This won't allow the form to be submitted by pressing Enter. You're better off removing the button's `onClick` handler completely (causing the button to submit the form) and putting your handler on the `onSubmit` event instead, ensuring you keep the `preventDefault()` call in your handler to stop the old-style form submission. – Malvineous Jul 25 '22 at 02:44
8

2 ways

First one we pass the event in the argument right into the onClick.

  onTestClick(e) {
    e.preventDefault();
    alert('here');
  }

  // Look here we pass the args in the onClick
  <Button color="primary" onClick={e => this.onTestClick(e)}>primary</Button>&nbsp;

Second one we pass it into argument and we did right in the onClick

  onTestClick() {
    alert('here');
  }

  // Here we did right inside the onClick, but this is the best way
  <Button color="primary" onClick={e => (e.preventDefault(), this.onTestClick())}>primary</Button>&nbsp;

Hope that can help

EQuimper
  • 5,811
  • 8
  • 29
  • 42
4

In your onTestClick function, pass in the event argument and call preventDefault() on it.

function onTestClick(e) {
    e.preventDefault();
}
Soviut
  • 88,194
  • 49
  • 192
  • 260
  • 1
    Tried that and it did not work. In fact, when I look at the component's code, it's already doing that. The code can be seen here: https://github.com/reactstrap/reactstrap/blob/master/src/Button.js – Some User Oct 02 '16 at 11:51
  • I added that to the fiddle and it worked fine, the only time they are doing that for you is if you passed in `this.props.disabled = true` on the Button component – finalfreq Oct 03 '16 at 22:46
4
import React, { Component } from 'react';

export class Form extends Component {
  constructor(props) {
    super();
    this.state = {
      username: '',
    };
  }
  handleUsername = (event) => {
    this.setState({
      username: event.target.value,
    });
  };

  submited = (event) => {
    alert(`Username: ${this.state.username},`);
    event.preventDefault();
  };
  render() {
    return (
      <div>
        <form onSubmit={this.submited}>
          <label>Username:</label>
          <input
            type="text"
            value={this.state.username}
            onChange={this.handleUsername}
          />
          <button>Submit</button>
        </form>
      </div>
    );
  }
}

export default Form;
Sakil Khan
  • 140
  • 5
  • 2
    This question already contains multiple answers and an accepted answer. Can you explain (by editing your answer) where your answer differs from the other answers? Also know that Code-only answers are not useful in the long run. – 7uc1f3r Oct 03 '20 at 08:13
3

You have prevent the default action of the event and return false from the function.

function onTestClick(e) {
    e.preventDefault();
    return false;
}
Gokhan Kurt
  • 8,239
  • 1
  • 27
  • 51
3

There's another, more accessible solution: Don't put the action on your buttons. There's a lot of functionality built into forms already. Instead of handling button presses, handle form submissions and resets. Simply add onSubmit={handleSubmit} and onReset={handleReset} to your form elements.

To stop the actual submission just include event in your function and an event.preventDefault(); to stop the default submission behavior. Now your form behaves correctly from an accessibility standpoint and you're handling any form of submission the user might take.

dougoftheabaci
  • 665
  • 1
  • 6
  • 19
2
function onTestClick(evt) {
  evt.stopPropagation();
}
fvgs
  • 21,412
  • 9
  • 33
  • 48
1
import React from 'react'
import Button from './button'
import Input from './input'

function Form(){

    function handleSubmit(event){
        event.preventDefault();
    }

    return(
        <div>
            <h1>FORM</h1>
            <form onSubmit={handleSubmit}>
                <Input type = 'text' placeholder = "What's Your Name?" />
                <Button buttonText = 'Submit' />
            </form>
        </div>
    );
}

export default Form;
0

I was facing this problem when I used preventDefault() with destructuring. It worked perfectly fine without destructuring:

// this works
const handleClick = (evt) => {
   evt.preventDefault();
}

// this doesn't work
const handleClick = ({preventDefault}) => {
   preventDefault();
}
Aakash
  • 21,375
  • 7
  • 100
  • 81
-1
<button type="submit" onClick={(e)=> this.submitInfo(e)}>Prevent Submit</button>

And the function

submitInfo = (event)=>{
    event.preventDefault();
      .....

}
-8
componentDidUpdate(){               
    $(".wpcf7-submit").click( function(event) {
        event.preventDefault();
    })
}

You can use componentDidUpdate and event.preventDefault() to disable form submission.As react does not support return false.