How to submit form from a button outside that component in React?

You can achieve this by using regular HTML capabilities (HTML form Attribute), no need to use the React hacks:

Add "id" attribute to your form: id='my-form'

class CustomForm extends Component {
    render() {
        return (
             <form id='my-form' onSubmit={alert('Form submitted!')}>
                // Form Inputs go here    
             </form>
        );
    }
}

Then add the same Id to the "form" attribute of the target button outside of the form:

<button form='my-form' type="submit">Outside Button</button>

Now, the 'Outside Button' button will be absolutely equivalent as if it is inside the form.

Note: This is not supported by IE11.


Edit: Simple and correct answer: https://stackoverflow.com/a/53573760/5271656

In React, data flows down and actions flow up. So notify child component about button click in the parent.
This is how you can do this.

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

class CustomForm extends Component {
  handleOnSubmit = e => {
    e.preventDefault();
    // pass form data
    // get it from state
    const formData = {};
    this.finallySubmit(formData);
  };

  finallySubmit = formData => {
    alert("Form submitted!");
  };

  componentDidUpdate(prevProps, prevState) {
    if (this.props.submitFromOutside) {
      // pass form data
      // get it from state
      const formData = {};
      this.finallySubmit();
    }
  }

  render() {
    return (
      <form onSubmit={this.handleOnSubmit}>
        <button type="submit">Inside Custom</button>
      </form>
    );
  }
}

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      submitFromOutside: false
    };
  }
  submitCustomForm = () => {
    this.setState({
      submitFromOutside: true
    });
  };

  componentDidMount() {
    console.log(this.form);
  }

  render() {
    return (
      <div>
        <CustomForm submitFromOutside={this.state.submitFromOutside} />
        <button onClick={this.submitCustomForm}>In Root</button>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);  

To me, this solution is hacky and not in a react way but serves your use-case.
Find working solution here:https://codesandbox.io/s/r52xll420m

Tags:

Reactjs