简体   繁体   English

React JS,一个表单中的两个提交按钮

[英]React JS, two submit buttons in one form

When using React JS, how can I identify which button was used to submit the form?使用 React JS 时,如何识别提交表单时使用的是哪个按钮?

I thought something like this would work, but it doesn't:我认为这样的事情会起作用,但它不起作用:

export default function App() {
  const onSubmit = e => {
    e.preventDefault();
    console.log(e.target.btn.value);
  };

  return (
    <form className="App" onSubmit={onSubmit}>
      <button type="submit" name="btn" value="wow">
        Button 1
      </button>
      <button type="submit" name="btn" value="oh no">
        Button 2
      </button>
    </form>
  );
}

Code sandbox代码沙箱

According to standard HTML you should be able to name two buttons the same name?根据标准 HTML 你应该可以命名两个相同名称的按钮吗? Or use formaction attribute to distinguish them.或者使用formaction属性来区分它们。

In my use case the buttons don't have knowledge about the form.在我的用例中,按钮不了解表单。 I want to avoid a solution where I use some temporary state to remember which button was clicked.我想避免使用一些临时的 state 来记住单击了哪个按钮的解决方案。

In standard HTML you can do this:在标准 HTML 中,您可以这样做:

<form action="/action_page.php">
  <input type="submit" name="btn" value="Submit">
  <input type="submit" name="btn" value="Submit2">
</form> 

When you submit the form btn will either be posted Submit or Submit2 depending on which button you click.当您提交表单时, btn将根据您单击的按钮发布SubmitSubmit2 I want to get as close as possible to this standard when building my React form.我想在构建我的 React 表单时尽可能接近这个标准。 Use as little help from Javascript and React as possible.尽可能少地使用 Javascript 和 React 的帮助。 Basically just add the buttons to the DOM inside my form and collect the values from the event that I have access to inside of the submit handler.基本上只需将按钮添加到我的表单内的 DOM,并从我有权访问的提交处理程序内部的事件中收集值。

Try using event.submitter.name property.尝试使用event.submitter.name属性。 Add different name to your buttons and check their names in eventHandler .为按钮添加不同的name并在eventHandler检查它们的名称。 If you use some kind of library for making forms it may lay in e.nativeEvent.submitter.name如果您使用某种库来制作表单,它可能位于e.nativeEvent.submitter.name
More info https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter更多信息https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter

Either you can try the below code or you can try to make separate calls for both buttons.您可以尝试以下代码,也可以尝试分别调用两个按钮。

Demo link codesandox演示链接codeandox

import React from "react";
import "./styles.css";

export default function App() {
  const state = {
    button: 1
  };

  const onSubmit = e => {
    e.preventDefault();
    if (state.button === 1) {
      console.log("Button 1 clicked!");
    }
    if (state.button === 2) {
      console.log("Button 2 clicked!");
    }
  };

  return (
    <form className="App" onSubmit={onSubmit}>
      <button
        onClick={() => (state.button = 1)}
        type="submit"
        name="btn1"
        value="wow"
      >
        Button 1
      </button>
      <button
        onClick={() => (state.button = 2)}
        type="submit"
        name="btn2"
        value="oh no"
      >
        Button 2
      </button>
    </form>
  );
}

You can determine which button was clicked by checking which element currently has focus using document.activeElement in the onSubmit function.您可以通过使用 onSubmit 函数中的document.activeElement检查当前具有焦点的元素来确定单击了哪个按钮。 Add different ids or data attributes to the buttons to determine which one was clicked.向按钮添加不同的 id 或数据属性以确定单击了哪个按钮。

Working with forms in ReactJS is rather straight forwards, if you know how input works.如果您知道输入是如何工作的,那么在 ReactJS 中使用表单是相当直接的。 Here is some more information directly from the documentation: https://reactjs.org/docs/forms.html以下是直接来自文档的更多信息: https : //reactjs.org/docs/forms.html

And here is a small example which I will explain for you:这是一个小例子,我将为您解释:

      // You need to add a onSubmit event to the form. This will trigger when you submit the for as you do any other html form (including pressing the submit button)
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          // need to save input value somewhere (use the state for this, check the link from above
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        // this is your button, as with other html forms.
        <input type="submit" value="Submit" />
      </form>

In the case you described, you shouldn't really submit the data inside the buttons (why would you do that?), but instead submit the form data inside inputs.在您描述的情况下,您不应该真正提交按钮内的数据(为什么要这样做?),而是提交输入内的表单数据。 If you really want two buttons for submit (although a form can be submitted by hitting the key enter for example), you can do so like this:如果你真的想要两个提交按钮(尽管可以通过按enter键提交表单),你可以这样做:

    // onSubmit is the same as before, handle form data here
    <form className="App" onSubmit={onSubmit}>
      // setSubmitButton would set the submit button to button1 (e.g. use react state for this)
      <button type="submit" onClick={setSubmitButton('button1')} name="btn" value="wow">
        Button 1
      </button>
      <button type="submit" onClick={setSubmitButton('button2')} name="btn" value="oh no">
        Button 2
      </button>
    </form>

As far as I understand from comments you want to have 2 submit buttons: one to "Save As Draft" another to "Submit".据我从评论中了解到,您希望有 2 个提交按钮:一个用于“另存为草稿”,另一个用于“提交”。

I have this solution.我有这个解决方案。

In DB for your post make a Boolean field "finished".在数据库中为您的帖子制作一个布尔字段“完成”。 If "finished" is "false" it's a draft, if "true" it's submitted.如果“finished”为“false”,则为草稿,如果为“true”,则为提交。

Using React functional component in frontend set component state:在前端设置组件状态中使用 React 功能组件:

 const [finished, setFinished] = useState(false);

Then you have a form with "submitHandler" that saves it to DB and 2 submit buttons that set "finished" to true or false然后你有一个带有“submitHandler”的表单,将它保存到数据库和 2 个将“完成”设置为 true 或 false 的提交按钮

 <form onSubmit={submitHandler}>
       //your other fields
       <button type="submit" onClick={() => setFinished(false)}">
         Save as a Draft
       </button>
       <button type="submit" onClick={() => setFinished(true)}>
         Submit
       </button>
    </form>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM