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

问题描述 投票:0回答:5

使用 React JS 时,如何识别提交表单时使用的是哪个按钮?

我以为这样的事情会奏效,但事实并非如此:

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

代码沙箱

根据标准的 HTML 你应该可以给两个按钮命名相同的名字?或者使用

formaction
属性来区分它们。

在我的用例中,按钮不了解表单。我想避免使用一些临时状态来记住单击了哪个按钮的解决方案。

在标准 HTML 中,您可以这样做:

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

当您提交表格时,

btn
将被发布
Submit
Submit2
,具体取决于您单击的按钮。我想在构建我的 React 表单时尽可能接近这个标准。尽可能少地使用 Javascript 和 React 的帮助。 基本上只需将按钮添加到我的表单内的 DOM,并从我有权访问的提交处理程序内部的事件中收集值。

javascript reactjs form-submit
5个回答
18
投票

尝试使用

event.submitter.name
属性。添加不同的
name
到您的按钮,并在
eventHandler
中检查它们的名称。 如果您使用某种库来制作表格,它可能位于
e.nativeEvent.submitter.name

更多信息https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter


2
投票

您可以尝试以下代码,也可以尝试分别调用两个按钮。

演示链接codesandox

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

1
投票

如果你知道输入是如何工作的,那么在 ReactJS 中使用表单是相当简单的。以下是直接来自文档的更多信息:https://reactjs.org/docs/forms.html

这里有一个小例子,我会为你解释:

      // 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>

在您描述的情况下,您不应该真正提交按钮内的数据(为什么要这样做?),而是提交输入内的表单数据。如果你真的想要两个提交按钮(虽然一个表单可以通过点击键

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>

1
投票

您可以通过在 onSubmit 函数中使用

document.activeElement
检查哪个元素当前具有焦点来确定单击了哪个按钮。为按钮添加不同的 id 或数据属性,以确定点击了哪个按钮。


0
投票

我使用 e.nativeEvent.submitter。只要 react/nextjs 不支持它,我就使用以下 kludge 来使 typescript 快乐:

function getSubmitter(e: Event & { submitter?: HTMLButtonElement} ):
    HTMLButtonElement|undefined
{
    return e?.submitter;
}

function example(): JSX.Element {
    const handleSubmit = async (e:  React.FormEvent<HTMLFormElement>):
        Promise<void> =>
    {
        e.preventDefault();
        var btn = getSubmitter(e.nativeEvent);
        if (btn?.id == 'clear') {
            clearScreen();
            return;
        }
        //...
    }

    return (
        <form action='/check' method='post' onSubmit={handleSubmit}>
            <button type="submit" id="clear">Clear Screen</button>
            <button type="submit" id="store">Store</button>
            // ...
        </form>
    )
}
© www.soinside.com 2019 - 2024. All rights reserved.