如何在 Ionic React 多按钮表单中执行 HTML5 验证?

How to perform HTML5 validation in Ionic React multi-button form?

在下面的CodeSandbox中点击Add按钮时,event.nativeEvent.submitter返回以下Button => <button type="submit" style="display: none;"></button>

https://codesandbox.io/s/lingering-fog-pe7jl?file=/src/App.tsx

是否可以正确识别触发 onSubmit 事件的 ion-button<button>
正确的按钮将有 aria-label=add 或在 <ion-button> 标签之间有“添加”。

也许单独渲染按钮并使用onClick事件会更好?

例如:

task && (
    <IonButton aria-label="update" type="button" color="secondary" onClick={ onTaskClick }>
    <IonIcon icon={ arrowUpCircleOutline }></IonIcon>
         Update
    <IonButton>

    <IonButton aria-label="delete" type=button" color="danger" onClick={ onDeleteClick }>
    <IonIcon icon={ trashOutline }></IonIcon>
        Delete
    </IonButton>
)

使用此方法,可以更轻松地知道单击了哪个按钮。

使用点击事件并跟踪点击按钮的 id,您仍然可以使用 refs 提取表单值,参见示例 https://codesandbox.io/s/boring-babbage-y14zv?file=/src/App.tsx:415-2653

const Home: React.FC = () => {
  // const task: Task = {
  //   title: "Planning Tasks",
  //   time: "30m"
  // };
  const task = undefined;
  const nameRef = React.useRef<any>("");

  const onTaskSubmit = async (event: any) => {
    console.log(nameRef.current.value);
    console.log(event.target.id);

    switch (event.target.id) {
      case "update":
        console.log("Go to onTaskClick()");
        break;
      case "add":
        console.log("Go to onTaskClick()");
        break;
      case "delete":
        console.log("Go to onDeleteClick()");
        break;
      case "reset":
        nameRef.current.value = "";
        break;
    }
  };

  return (
    <IonPage id="home-page">
      <IonHeader>
        <IonToolbar>
          <IonTitle>Task Planner</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent fullscreen>
        <IonHeader collapse="condense">
          <IonToolbar>
            <IonTitle size="large">Tasks</IonTitle>
          </IonToolbar>
        </IonHeader>

        <form>
          <IonItem>
            <IonInput ref={nameRef} placeholder={"Enter Name"}></IonInput>
          </IonItem>

          {task ? (
            <IonButton
              aria-label={"update"}
              id={"update"}
              color={"secondary"}
              onClick={onTaskSubmit}
            >
              <IonIcon icon={arrowUpCircleOutline} slot="start"></IonIcon>
              {"Update"}
            </IonButton>
          ) : (
            <IonButton
              aria-label={"add"}
              id={"add"}
              color={"primary"}
              onClick={onTaskSubmit}
            >
              <IonIcon icon={addCircleOutline} slot="start"></IonIcon>
              {"Add"}
            </IonButton>
          )}

          <IonButton
            aria-label={task ? "delete" : "clear"}
            color="danger"
            id={task ? "delete" : "clear"}
          >
            {task ? (
              <IonIcon icon={trashOutline}></IonIcon>
            ) : (
              <IonIcon icon={closeCircleOutline}></IonIcon>
            )}
            &nbsp;
            {task ? "Delete" : "Clear"}
          </IonButton>
        </form>
      </IonContent>
    </IonPage>
  );
};

我能够在 onClick 函数内的 React ref 表单上使用 reportValidity() 并检查是否定义了 task 对象以确定单击了哪个按钮:

在 React 表单中使用 onSubmit 会产生不可预测的结果。

const Home: React.FC = () => {
  // const task: Task = {
  //   time: "30m"
  // };
  const task = undefined;

  const taskForm = useRef<HTMLFormElement>(null);
  const timeEl = useRef<any>('time');

  const onTaskClick = () => {
    if (! taskForm?.current?.reportValidity()) return;
    let taskData: Task = {
      time: (timeEl.current).value
    }

    if (task) {
      // update Task
    } else {
      // add Task
    }
  }

  return (
    <IonPage id="home-page">
      <IonHeader>
        <IonToolbar>
          <IonTitle>Task Planner</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent fullscreen>
        <IonHeader collapse="condense">
          <IonToolbar>
            <IonTitle size="large">Tasks</IonTitle>
          </IonToolbar>
        </IonHeader>

        <form ref={taskForm}>
          <IonInput ref={timeEl} value={task?.time} placeholder="Time" type="text" required={true} pattern="[\d+h]?[\d+m]?" />

          <IonButton onClick={onTaskClick} type="submit" color={task ? "secondary" : "primary"}>        
          {task
            ? <IonIcon icon={arrowUpCircleOutline}></IonIcon>
            : <IonIcon icon={addCircleOutline}></IonIcon>            
          }
          &nbsp;
          {task
            ? "Update"            
            : "Add"            
          }        
          </IonButton>

          <IonButton onClick={onDeleteClick} type={task ? "submit" : "reset"} color="danger">              
          {task
            ? <IonIcon icon={trashOutline}></IonIcon>
            : <IonIcon icon={closeCircleOutline}></IonIcon>            
          }
          &nbsp;
          {task
            ? "Delete"            
            : "Clear"            
          }
          </IonButton>
        </form>
      </IonContent>
    </IonPage>
  );
};