I Spent 5 Hours Trying to Figure Why My React Form Was Auto-submitting

So this week I was building a login form that uses the "Only email credentials" method. Meaning it consists of just 2 steps. The first step shows an email input & a 'Next' button, and the second step contains a 'code' input and a 'submit' button. I was using one form that contains both of the inputs and buttons. And a state variable that controls which one is being shown.

The first step button was a normal button, while the second one was a 'submit' type button. And in my code, the logic for that looked something like this:

{
  isFirstStep ? (
    <button type="button" onClick={next}>
      Next
    </button>
  ) : (
    <button type="submit">Submit</button>
  );
}

Pretty simple, right?? And it should work correctly, right?? ... ... ... right???

Well, as you might've guessed, it didn't. The moment I click the next button, it moves to the next step, but at the same time the form always gets submitted automatically...

This confused me quiet a lot, and I literally sat there for hours trying to figure out the reason for this problem. Maybe it's react-hook-form library? Maybe it's the validation code? Maybe it's the VerificationInput component? Maybe it's the form submission handler? I tried and tried literally for hours with no avail...😩

Then just out of debugging sake, I tried showing both of the buttons at the same time. And the problem disappeared... say what?! Okay, so I learned that the problem lies with the buttons. I tried to show/hide the button separately using && instead of ?, and the problem didn't appear too!! At this point I was very happy that the problem was solved, although I didn't quiet get why it was happening in the first place.

After a little bit of research and reading, I learned that react doesn't always create new DOM elements if it thinks that it can reuse the same element and just change something simple in it (like its text content, or data properties)

And this was the case in my situation, where using the ternary operator made React reuse the same button, but just change some of its properties. But when I used the && operator, React treated the 2 buttons as 2 different elements, not the same one anymore.

Bonus: Another way to explecitly tell react to create 2 different elements is to put different key props on the 2 buttons. And the problem won't appear even if you use the ternary operator in this case.

And that's it folks. Hope that you learned something from this, and that it saves you some hours later unlike me 😅

So until next time, and have a great day 👋

My Photo

About Me

I'm a freelance web developer who specializes in frontend.
I have a special love for React. And my personal goal is: Building things that are Awesome! ✨
If you are someone who is building a project where high quality is a MUST, then Let's Chat! I'll be glad to help you with it.

© 2023-present Mohammed Taher Ghazal. All Rights Reserved.