ZpfSysn
ZpfSysn

Reputation: 889

React ES5: one button invoked two functions

I have two react classes both have render function that returns forms with a button. In class A, I had to import class B so i can use form from class B.

My problem: When I clicked the inner button, the outer button gets triggered as well but I only want the inner submit button to work.

My attempt: I checked the console and found out that it is giving me a warning: validateDOMNesting: form cannot appear as a descendant of form.

I did the research and thought that the problem may due to the nested form . So I found out a workaround from SO by changing the <form></form> in the class B to <div></div>, so it is no longer a form. Now it does not give me error on console, but the problem still remains: if I click the inner button, the outer button got triggered as well which invoked two functions in total.

Where I need help: I really want to figure out what cause this behavior(I am thinking maybe changing the tag does not change the nested form problem or maybe the way how I referencing the other class is not completely right)

My code:(Please notice that I simplified it)

var classA = React.createClass({
  render: function() {
    return (
      <div>
        <form
          className={this.props.className}
          id={this.props.controllerSingular + '_form'}
          onSubmit={this.handleSubmit}
          ref="some_form"
        >
          <FieldSet>
            <ClassB id={this.state.id} />
          </FieldSet>
          <button onClick={this.submit} className="btn btn-primary">
            Save
          </button>
        </form>
      </div>
    )
  },
})

var classB = React.createClass({
  render: function() {
    return (
      <div>
        <button id="some_ID" className="some_name" onClick={this.handleRegAdd}>
          Add
        </button>
      </div>
    )
  },
  handleRegAdd: function() {
    var that = this
    var regLines = this.state.regulation
    regLines.push({
      reg_id: null,
      Type: $('.reg-type-select span.Select-value-label').text(),
      id: that.props.id,
      Hours: null,
      Minutes: null,
      Days: '',
      Start: null,
      End: null,
    })

    this.setState({
      regulations: regLines,
    })
  },
})

when I clicked the button from class B, which should only trigger function "handleRegAdd". However, it also triggered submit function in class A

Upvotes: 0

Views: 150

Answers (2)

Sia
Sia

Reputation: 9212

The default type for a button is submit, so to have the button not perform the form's onSubmit action, simply change the type to button:

<button type="button" id="some_ID" className="some_name" onClick={this.handleRegAdd}>
  Add
</button>

I mentioned this in my comment, and it's also covered here in this SO question: HTML button to NOT submit form

Upvotes: 0

BonsaiOak
BonsaiOak

Reputation: 28941

The error is not related to the validateDOMNesting warning.

Button clicks (and other DOM events) bubble up the component tree. That means that clicking on the button will trigger the onClick event for all parent components as well.

You can stop the bubbling by calling event.preventDefault() in your event handler. It might look like this:

handleRegAdd: function(event) {
  event.preventDefault()

  // continue with the rest of your code
}

Upvotes: 2

Related Questions