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

IT技术 reactjs
2021-04-02 02:26:17

我的一个 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单击按钮时实际提交表单

6个回答

您可以通过使用常规 HTML 功能(HTML 表单属性来实现这一点,无需使用 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>
        );
    }
}

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

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

现在,“外部按钮”按钮将完全等效,就好像它在表单内部一样。

注意:IE11 不支持此功能。

你知道我们可以通过什么方式在 IE11 中完成这项工作吗?@pubudu
2021-05-26 02:26:17
@Vidur 不幸的是没有。我强烈推荐该解决方案,该解决方案建议将 handleSubmit 作为来自父级的道具传递给您。此解决方案甚至适用于 IE8 等较旧的浏览器
2021-06-02 02:26:17

编辑:简单而正确的答案:https : //stackoverflow.com/a/53573760/5271656

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

对我来说,这个解决方案很笨拙,不是以react方式,而是为您的用例服务。
在这里找到工作解决方案:https : //codesandbox.io/s/r52xll420m

顺便说一句,你为什么说这不是一种反应方式,而是一种骇人听闻的解决方案?
2021-05-29 02:26:17
但我不明白为什么要在 CustomForm 组件中具有提交功能,那么为什么不能简单地在 App 组件中创建它并将其作为道具传递给自定义表单组件?
2021-06-15 02:26:17
@BhojendraRauniyar 正确的方法是将函数传递给孩子,孩子会在提交时调用它。但是要回答 OP 的用例,这是我能想到的唯一解决方案。ref也可以使用,但这需要将表单值发送给父级
2021-06-20 02:26:17

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

回答问题时可以尝试提供代码示例。只是说,它可以帮助人们更好地理解您的意思。
2021-06-01 02:26:17

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

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

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

提交按钮必须在表单之外。因此,这个答案没有贡献。
2021-05-25 02:26:17
@MurliPrajapati 啊,我明白了,我实际上采用 React 的方式做同样的事情,感谢您的指点。
2021-06-07 02:26:17
这不是 OP 想要的。App组件中的解决方案按钮中不会调用表单提交CustomForm
2021-06-10 02:26:17

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