【问题标题】:react-hook-form not working when onSubmit called调用 onSubmit 时,react-hook-form 不起作用
【发布时间】:2021-11-04 14:21:48
【问题描述】:

我正在尝试保存反应表单,然后更新一些用户设置。

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

【问题讨论】:

  • 如果 &lt;button&gt; 是一个普通的 html 标签而不是一个反应组件,它没有有效的 variant 属性。您尝试拦截按钮 onClick 事件并停止传播onClick={e =&gt; { e.stopPropagation(); e.preventDefault() }
  • 你能创建一个codesandbox吗?
  • @LeCoda,onSubmit = (values, e) =&gt; {e.preventDefault();} 怎么样?
  • 不幸的是不起作用

标签: javascript reactjs


【解决方案1】:

您在handleSubmitRemove 内调用onSubmit

handleSubmitRemove 中删除onSubmit 可能会起作用。

【讨论】:

  • 不幸的是,不要认为这是正确的。
【解决方案2】:

尝试在表单标签上使用 id 属性,即

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

在按钮标签上,您使用与表单ID相同的表单属性,即

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

【讨论】:

  • 试过了,可惜没用
【解决方案3】:

如果没有任何效果,请根据上述建议。

使用 preventDefault 进行提交

并使用不同的函数处理提交,使用 document.getElement 或 querySelector 获取您需要的所有数据并在函数中处理它们。

【讨论】:

    【解决方案4】:

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

    填写完必填项后,点击提交按钮,表单提交

    【讨论】:

      【解决方案5】:

      用 type="submit" 代替按钮尝试输入元素并设置样式

      【讨论】:

        【解决方案6】:

        您的 CodeSandbox 链接无法为我编译,但请查看 RHF github 上的 this discussion,了解如何防止在提交处理程序中提交表单。它涉及异步的东西,但应该与您的需求相似。我认为您只需要像其他人所说的那样传递事件和 preventDefault ,也许他们的示例值得效仿。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-07-28
          • 2020-06-24
          • 2021-09-13
          • 2021-06-19
          • 1970-01-01
          • 2021-10-05
          • 2022-08-17
          相关资源
          最近更新 更多