如何从React中该组件外部的按钮提交表单?

时间:2018-09-30 10:41:48

标签: reactjs

我在我的一个React组件中有一个表单,在调用它的外部组件中,我想传递对该按钮的引用,以便我也可以使用该按钮提交该表单。

为了更加清楚,我有以下内容:

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

class CustomForm extends Component {
  render() {
    return (
      <form onSubmit={alert('Form submitted!')}>
        <button type='submit'>Inside Custom</button>
      </form>
    );
  }
}

function App() {
  return (
    <div>
      <CustomForm />
      <button>In Root</button>
    </div>
  );
}

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

现在,我可以使用标题为“ Inside Custom”的按钮提交表单,但我也希望能够使用位于根组件中的标题为“ In Root”的按钮提交表单。是否可以通过某种方式将引用从该按钮传递到该自定义组件,并在单击In Root按钮时实际提交表单?

7 个答案:

答案 0 :(得分:2)

在React中,数据流向下,动作流向上。因此,通知子组件有关父级中按钮单击的信息。
这就是您可以执行的操作。

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);  

对我来说,此解决方案是很棘手的,不是以一种反应的方式,而是适合您的用例。 在此处找到有效的解决方案:https://codesandbox.io/s/r52xll420m

答案 1 :(得分:2)

您可以通过使用常规HTML功能(HTML form Attribute)来实现此目的,而无需使用React hacks:

在您的表单中添加“ id”属性:id ='my-form'

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

然后在表单之外的目标按钮的“表单”属性中添加相同的ID:

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

现在,“外部按钮”按钮将完全等同于表单内部。

注意:IE11不支持此功能。

答案 2 :(得分:1)

您可以将onSubmit点击处理程序作为道具传递,如下所示:

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

class CustomForm extends Component {

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

function App() {
 handleSubmit = () => {
   alert('Form submitted!')
}
  return (
    <div>
      <CustomForm onSubmit={this.handleSubmit} />
      <button>In Root</button>
    </div>
  );
}

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

传递功能作为处理表单提交的道具,使CustomForm元素更可重用,因为提交的业务逻辑不是CustomForm组件的一部分。

答案 3 :(得分:1)

您可以在状态中设置标志属性,例如rootBtnClicked: false和一种处理App组件中的单击的方法。同样在<CustomForm />中,添加一个道具,例如rootBtnClicked={this.state.rootBtnClicked}。单击“在根目录”按钮时,触发该方法;然后该方法使用setState()更改状态。然后在CustomForm组件的render()方法中,检查prop是否为true。如果是,请使用React的.submit()手动触发ref

答案 4 :(得分:0)

您可以将Submit函数作为道具传递,并在需要时使用此方法。 对于更复杂的情况,您可以使用redux将表单数据保存在redux上,每当单击按钮时,您就会从redux读取数据并提交

答案 5 :(得分:0)

这些解决方案都不适合我,但是我终于做到了

document.forms[0].submit()

由于页面上只有一个表单,所以我使用0索引来选择它,但是如果有多个表单,则需要对表单数组使用适用的索引。

答案 6 :(得分:0)

好吧,设置一个类型为 submit 且属性为 form 的按钮,其值等于您要提交的表单的 id