ReactJS表单:使用两个提交按钮执行同一表单的两个不同任务

3

我希望我的表单有两个提交按钮。

两个按钮都会使用相同的输入和表单验证,但会执行不同的任务。

export default function Formtwosubmits() {

  function handlesubmit_task1(){


  }


  function handlesubmit_task2(){


  }


  return (
    <>
      <form onSubmit={handlesubmit_task1 if task 1 button pressed || handlesubmit_task2 if task2 button pressed } >
        <Button variant="contained" color="primary" type="submit">
          task 1
        </Button>

        <Button variant="contained" color="primary" type="submit">
          task 2
        </Button>
        .... here input fields
      </form>
    </>
  );
}

我不明白如何为不同的按钮传递不同的处理函数。

我尝试过:

export default function Formtwosubmits() {

  function handlesubmit_task1(){


  }


  function handlesubmit_task2(){


  }


  return (
    <>
      <form >
        <Button variant="contained" color="primary" type="submit" onClick={handlesubmit_task1}>
          task 1
        </Button>

        <Button variant="contained" color="primary" type="submit" onClick={handlesubmit_task2}>
          task 2
        </Button>
        .... here input fields
      </form>
    </>
  );
}


在按钮上使用onClick,而且类型为submit,但这样不会检查表单验证(例如必填等),而使用onSubmit可以看到表单验证被检查。
如何使用onClick触发表单验证。这可能对我有所帮助。
4个回答

4

使用 React 的 ref 在 form 元素上,以便在提交处理程序中访问表单字段,并将提交处理程序附加到每个按钮的 onClick 处理程序。

function Formtwosubmits() {
  const formRef = useRef(); // (1) <-- React ref for form DOMNode

  function handlesubmit_task1(event) {
    event.preventDefault();
    const { value } = formRef.current.myInput; // (4) <-- access form inputs by name

    // ...anything you need to do with form fields
    console.log("handler 1", value);

    formRef.current.reset(); // (5) <-- reset form if necessary
  }
  
  function handlesubmit_task2(event) {
    event.preventDefault();
    const { value } = formRef.current.myInput;

    console.log("handler 2", value);

    formRef.current.reset();
  }

  return (
    <>
      <form ref={formRef}> // (2) <-- Attach ref to element
        <button
          variant="contained"
          color="primary"
          type="submit"
          onClick={handlesubmit_task1} // (3) <-- Attach submit handler 1
        >
          task 1
        </button>
        <button
          variant="contained"
          color="primary"
          type="submit"
          onClick={handlesubmit_task2} // (3) <-- Attach submit handler 2
        >
          task 2
        </button>
        .... here input fields
        <input name="myInput" type="text" />
      </form>
    </>
  );
}

演示

Edit reactjs-form-with-two-submit-buttons-doing-two-different-tasks-for-same-form

更新

您可以为每个提交按钮分配一个id,并访问React合成事件的nativeEvent,以获取底层浏览器事件并访问submitter的值。

创建一个submitHandler函数来接收表单的onSubmit事件,然后检查id的值,并根据情况将onSubmit事件代理到正确的处理程序中。

const handlers = {
  submit1: handlesubmit_task1,
  submit2: handlesubmit_task2,
}

const submitHandler = (e) => {
  const { id } = e.nativeEvent.submitter; // <-- access submitter id
  handlers[id](e); // <--proxy event to proper callback handler
};

function handlesubmit_task1(event) {
  event.preventDefault();
  const { value } = event.target.myInput;
  console.log("handler 1", value);
  event.target.reset();
}

function handlesubmit_task2(event) {
  event.preventDefault();
  const { value } = event.target.myInput;
  console.log("handler 2", value);
  event.target.reset();
}

<form onSubmit={submitHandler}>
  <button
    id="submit1" // <-- id 1
    variant="contained"
    color="primary"
    type="submit"
  >
    task 1
  </button>
  <button
    id="submit2" // <-- id 2
    variant="contained"
    color="primary"
    type="submit"
  >
    task 2
  </button>
  .... here input fields
  <input name="myInput" type="text" />
</form>

Edit reactjs-form-with-two-submit-buttons-doing-two-different-tasks-for-same-form (forked)


如果我们将函数改为异步常量,例如将function handlesubmit_task1(event) { }更改为const onSubmitA = async (data) => { },并将function handlesubmit_task2(event) { }更改为const onSubmitB = async (data) => { },会怎样呢?我看到你使用了evente,但如果我们传递异步数据,例如async (data),会发生什么? - uberrebu
@uberrebu,你是如何在将提交处理程序附加到表单元素的onSubmit处理程序时传递额外的“数据”的?你是在询问是否可以使onSubmit回调“异步”吗?这听起来会成为SO上很棒的新文章。如果你决定创建一篇新文章并带有相应的[mcve],请在此处在评论中@我,并附上链接,我可以在有空时查看它。 - Drew Reese
好的,我会将问题发布为新帖子并告诉你。谢谢。你是 Stack Overflow 上最棒的 React 专家! - uberrebu

1

You could write it like this:

export default function App() {
  function handleSubmitTask1() {
    console.log("Execute Task1");
  }

  function handleSubmitTask2() {
    console.log("Execute Task2");
  }

  return (
    <form
      onSubmit={(e) => {
        const buttonName = e.nativeEvent.submitter.name;
        if (buttonName === "button1") handleSubmitTask1();
        if (buttonName === "button2") handleSubmitTask2();
      }}
    >
      <input name="123" />

      <button type="submit" name="button1">
        task 1
      </button>
      <button type="submit" name="button2">
        task 2
      </button>
    </form>
  );
}

主要目的是获取触发表单提交的按钮名称。

这也是一个解决方案。谢谢。两者都是解决方案,而且采用了完全不同的方法。 - Santhosh

0

以下方法对我有用,使用 event.nativeEvent.submitter.id

表格 (注意每个按钮的id属性值是不同的):

<form onSubmit={this.testHandle}>
  <input type="submit" id="btn1" value="Submit button 1" />
  <input type="submit" id="btn2" value="Submit button 2" />
</form>

处理程序:

testHandle(event) {
  console.log(event.nativeEvent.submitter.id);
  event.preventDefault();
}

它成功地在控制台中打印出btn1btn2,具体取决于您单击表单的哪个按钮。

注意:使用React 18.2.0版本。


0

在按钮上使用onClick,并添加type='submit'以提交它。

export default function Formtwosubmits() {

  function handlesubmit_task1(e){


  }


  function handlesubmit_task2(e){


  }


  return (
    <>
      <form >
        <Button variant="contained" color="primary" type="submit" onClick={handlesubmit_task1}>
          task 1
        </Button>

        <Button variant="contained" color="primary" type="submit" onClick={handlesubmit_task2}>
          task 2
        </Button>
        .... here input fields
      </form>
    </>
  );
}

请检查我的修改后的问题。我已经尝试过这个,但表单验证没有完成。 - Santhosh
你正在使用引号"handlesubmit_task1",而不是花括号将其包裹。 - Shreyas Jadhav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接