React form error: Form submission canceled because the form is not connected

2.1k views Asked by At

I have a form inside a class component. When I submit the form, I get a warning Form submission cancelled because the form is not connected. There are no errors—just a warning.

I have linked it to my netlify site. I have added all the form data properties that are required to send the data to netlify.

I have used styled-components for styling.

Not sure, what I am missing.

class ContactThreeForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "",
      email: "",
      phone: "",
      message: "",
      error: false,
    };
  }

  formSubmit() {
    if (
      this.state.name === "" ||
      this.state.email === "" ||
      this.state.phone === "" ||
      this.state.message === ""
    ) {
      this.setState({ error: true });
    } else {
      this.setState({ error: false });
    }
    this.forceUpdate();
  }

  check(val) {
    if (this.state.error && val === "") {
      return false;
    } else {
      return true;
    }
  }

  render() {
    return (
      <ContactForm>
        <Heading>Get In Touch</Heading>
        <Separator />

        <form
          name="contact"
          method="POST"
          netlify-honeypot="bot-field"
          data-netlify="true"
          data-netlify-recaptcha="true"
        >
          <InputElement>
            <Input
              type="text"
              defaultValue={this.state.name}
              className={`name ${this.check(this.state.name) ? "" : "error"}`}
              placeholder="Name"
              onChange={(e) => this.setState({ name: e.target.value })}
            />
          </InputElement>
          <InputElement>
            <Input
              type="text"
              defaultValue={this.state.email}
              className={`email ${this.check(this.state.email) ? "" : "error"}`}
              placeholder="Email"
              onChange={(e) => this.setState({ email: e.target.value })}
            />
          </InputElement>
          <InputElement>
            <Input
              type="text"
              defaultValue={this.state.phone}
              className={`phone ${this.check(this.state.phone) ? "" : "error"}`}
              placeholder="Phone"
              onChange={(e) => this.setState({ phone: e.target.value })}
            />
          </InputElement>
          <InputElement>
            <Textarea
              placeholder="Message"
              defaultValue={this.state.message}
              className={`message ${
                this.check(this.state.message) ? "" : "error"
              }`}
              onChange={(e) => this.setState({ message: e.target.value })}
            />
          </InputElement>
          <Submit onClick={() => this.formSubmit()}>
            <span>Submit</span>
          </Submit>
        </form>
      </ContactForm>
    );
  }
}
1

There are 1 answers

0
Eric Haynes On BEST ANSWER

The browser's default handling of a form submission is to make an HTTP POST request to the server and reload the page with whatever is in the response (which may or may not even be content the browser can render). This is almost never what you want in a single page application, because your entire app and all of its state is simply discarded.

Instead of wiring up the form submit as a click handler on the submit button, you should instead wire it up as the onSubmit event of the form. You also want to call preventDefault() on the event, which prevents the native browser behavior. The button doesn't need a click handler at all as long as it has the attribute type="submit" (presumably, inside of your Submit component, there is a regular button element).


formSubmit(event) {
  event.preventDefault();
  // your submit logic
}

render() {
  // ...
  <form onSubmit={(event) => this.formSubmit(event)} 
    // ... Inside `Submit` should be something like:
    <button type="submit" />
  </form>
}