簡體   English   中英

當 onSubmit 調用時,react-hook-form 不起作用

[英]react-hook-form not working when onSubmit called

我正在嘗試保存反應表單,然后更新一些用戶設置。

import React, { useState, useEffect } from "react";
import Dropdown from "components/Settings/Preferences/Dropdown";
import { useForm } from "react-hook-form";

function Pill({ value, handleChange,optionName,substanceKey,key }) {
    return (
      <div  className="bg-gray-600 text-white text-xs px-2 py-0.5 w-max-content rounded-lg align-middle mr-1 mb-1">
        {value}
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="16"
          height="16"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
          className="inline-block align-middle cursor-pointer"
          onClick={() => handleChange(value, "remove",optionName,substanceKey)}
        >
          <line x1="18" y1="6" x2="6" y2="18" />
          <line x1="6" y1="6" x2="18" y2="18" />
        </svg>
      </div>
    );
  }

function InventoryPage(props) {
    const [substanceDetails, setSettings] = useState(
        [
          {
            substance: "Modafinil",
            scheduledtimes: [8, 13],
            startdate: "1996-12-02",
            enddate: "2020-01-01",
            duration: 2,
            planneddose: "10mg"
          },
          {
            substance: "Coveve",
            scheduledtimes: [8, 12],
            startdate: "1996-12-02",
            enddate: "2020-01-01",
            duration: 2,
            planneddose: "10mg"
          }
      );


      const { register, handleSubmit,watch, errors,formState } = useForm();
      const handleChange = (value, mode,optionName,substanceKey) => {
        var removedSubstances ;
        if(mode==="remove") {
          if (optionName === "substance" ) {
            removedSubstances = substanceDetails.find(v=> v.substance === value) ? substanceDetails.filter(v => v.substance !== value) : [...substanceDetails, value]
          }
         
       else {
          removedSubstances = substanceDetails.reduce((acc, key) => {
      //  return acc; // remove keys
        if (optionName === "scheduledtimes") { //works
          // remove 14 in times for keys
          return [...acc, { ...key,
            scheduledtimes: key.scheduledtimes.filter(time => time !== value)
          }]
        }
        if (optionName === "planneddose") {
          // modify the power by concatenating an new object with partial info
          if (key.substance == substanceKey){
      
          return [...acc, {...key,
            planneddose: null
          }];
        } else {
          return [...acc, {...key,
            planneddose: key.planneddose
          }];
        }
        }
      
        if (optionName === "startdate") {
          // modify the power by concatenating an new object with partial info
          if (key.substance == substanceKey){
      
          return [...acc, {...key,
            startdate: null
          }];
        } else {
          return [...acc, {...key,
            startdate: key.startdate
          }];
        }
        }
        if (optionName === "enddate") {
          // modify the power by concatenating an new object with partial info
          if (key.substance == substanceKey){
      
          return [...acc, {...key,
            enddate: null
          }];
        } else {
          return [...acc, {...key,
            enddate: key.enddate
          }];
        }
        }
      
        if (optionName === "duration") {
          // modify the power by concatenating an new object with partial info
          if (key.substance == substanceKey){
      
          return [...acc, {...key,
            duration: null
          }];
        } else {
          return [...acc, {...key,
            duration: key.duration
          }];
        }
        }
        
      }
      , []);
       }
      setSettings(removedSubstances)
        }
      };
  const onSubmit = data => console.log(data);
  const [pending, setPending] = useState(false);
  
   
  console.log(watch("example")); // watch input value by passing the name of it

  if (substanceDetails === false) {
    return (
      <div className="md:grid md:grid-cols-3 md:gap-6">
        <div className="md:col-span-1">
          <h3 className="text-lg font-medium leading-6 text-gray-900">
            Substances
          </h3>
        </div>
        <div className="mt-5 md:mt-0 md:col-span-2 font-mono font-medium text-blue-500">
          loading...
        </div>
      </div>
    );
  }
  

  return (
    <div className="md:grid md:grid-cols-3 md:gap-6">

    <div className="mt-5 md:mt-0 md:col-span-2">
     <form onSubmit={handleSubmit(onSubmit)} id="formName">
          <div className="flex flex-wrap mt-2">
            {substanceDetails &&
              substanceDetails.map((subst) => (
                <Pill
                  registerInput={register}
                  optionLabel="substance"
                  value={subst.substance}
                  key={subst.substance}
                  substanceKey = {subst.substance}
                  optionName={"substance"}
                  // allOptions={["Dexamphetamine", "Ritalin"]}
                  handleChange={handleChange}
                  error={formState.errors?.content ? true : false}
                />
              ))}
          </div>
          <Dropdown
            registerInput={register}
            optionLabel="Substance"
            selectedOption={substanceDetails.substance}
            optionName={"substance"}
            allOptions={["Dexamphetamine", "Ritalin"]}
            error={formState.errors?.content ? true : false}
          />
          <button
            className="inline-flex items-center justify-center px-5 py-2 border border-transparent text-base leading-6 font-medium rounded-md text-indigo-700 bg-indigo-100 hover:text-indigo-600 hover:bg-indigo-50 focus:outline-none focus:shadow-outline focus:border-indigo-300 transition duration-150 ease-in-out"
            variant={props.buttonColor}
            size={props.inputSize}
            type="submit"
            disabled={pending}
            form="formName"

          >
            {pending ? (
              <>
                <span>Saving</span>
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  viewBox="0 0 24 24"
                  className="animate-spin h-4 w-4 ml-3 fill-current"
                >
                  <path d="M0 11c.511-6.158 5.685-11 12-11s11.489 4.842 12 11h-2.009c-.506-5.046-4.793-9-9.991-9s-9.485 3.954-9.991 9h-2.009zm21.991 2c-.506 5.046-4.793 9-9.991 9s-9.485-3.954-9.991-9h-2.009c.511 6.158 5.685 11 12 11s11.489-4.842 12-11h-2.009z" />
                </svg>
              </>
            ) : (
              <span>Save</span>
            )}
          </button>
        </form>
    </div>
    </div>
  );
}

export default InventoryPage;

目前,當點擊提交時,表單本身只是刷新頁面,而不是使用 onSubmit 常量。 我不確定發生了什么,喜歡一些幫助:)

沙盒鏈接,代碼正在編譯但可能更容易審查代碼本身

https://codesandbox.io/s/using-tailwind-with-nextjs-forked-nnr0l?file=/pages/index.js

您正在 handleSubmit 內調用 onSubmit。 刪除它,我覺得你的代碼會正常工作。

嘗試使用表單標簽上的 id 屬性,即

<form onSubmit={handleSubmit(onSubmit)} id="formName">

在按鈕標簽上,您使用與表單 ID 相同的表單屬性,即

<button 
  variant={props.buttonColor} 
  size={props.inputSize} 
  type="submit" 
  disabled={pending}
  form="formName"
>

如果沒有任何效果,從上面的建議。

使用 preventDefault 提交

並使用不同的函數處理提交,使用 document.getElement 或 querySelector 獲取您需要的所有數據,並在函數中處理它們。

請看一下這個例子https://codesandbox.io/s/using-tailwind-with-next-js-forked-tizjq?file=/pages/index.js

填寫必填字段后點擊提交按鈕,表單提交

您的 CodeSandbox 鏈接不會為我編譯,但請查看 RHF github 上有關如何防止提交處理程序中提交表單的 討論 它涉及異步內容,但應該與您的需求相似。 我認為你只需要像其他人所說的那樣傳遞事件和 preventDefault ,也許他們的例子值得效仿。

而不是按鈕嘗試使用 type="submit" 的輸​​入元素並設置它的樣式

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM