1

im using react and i try to make form with custom submit button (with div) but when i submit the form the page automatically refreshes, despite e.preventDefault my code :

 <form onSubmit={e => e.preventDefault()} className="form">
        <div
          onClick={e => {
            e.preventDefault();
            document.querySelector(".form").submit();
          }}
          id="button"
        >
          Submit
        </div>
      </form>

demo on code sandbox : https://codesandbox.io/s/bitter-pond-9fcnr

4
  • Any reason you're not using a button? Commented Aug 11, 2019 at 19:27
  • for better styling Commented Aug 11, 2019 at 19:32
  • @frannoo_ — Use a div introduces massive accessibility problems. Style the button instead. Commented Aug 11, 2019 at 19:39
  • Not to mention this issue would have never occurred if a button were used.... This error is due to how you are submitting the form (essentially, the interactive submit event is bypassed)... You do know you can style buttons, too, right? Commented Aug 11, 2019 at 19:45

2 Answers 2

3

As per the spec

form . submit()

Submits the form, bypassing interactive constraint validation and without firing a submit event.

This is why your onSubmit callback doesn't get called, and page is getting refreshed as per the normal browser behaviour.

I'd suggest a work around in this case:

import React, { useRef } from "react";
import ReactDOM from "react-dom";


function App() {
  const submitEl = useRef(null);
  const handleFormSubmit = e => {
    e.preventDefault();
  };

  const handleBtnClick = e => {
    e.preventDefault();
    submitEl.current.click();
  };

  return (
    <div className="App">
      <form onSubmit={handleFormSubmit} className="form">
        <div onClick={handleBtnClick} id="button">
          Submit
        </div>
        <input
          ref={submitEl}
          name="submit"
          type="submit"
          style={{ display: "none" }}
        />
      </form>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Sign up to request clarification or add additional context in comments.

1 Comment

I use this solution for react-hook-form. I needed to bind custom submit function (handleSubmit) to pagination and it works out well. thank you.
0

I came up with this solution but I don't know if it is the best idea:

  <form onSubmit={e => e.preventDefault()} >
        <div
          onClick={e => {
            e.preventDefault();
            document.querySelector(".hidden-button").click();
          }}
          id="button"
        >
          Submit
        </div>
        <button type="submit" id="hidden-button"/>
      </form>

and also in css :

#hidden-button{
      display: none;
    }

1 Comment

You should really be using refs for this.. It is bad practices, and an anti-pattern, to directly interact with the DOM like this.. It can cause some odd things to happen (read more into the issues Discord just had due to directly interacting with the DOM).. More here

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.