为什么使用反应表单钩子在提交按钮内表单状态不会明显改变?

Joe*_*Joe 4 forms reactjs react-hooks react-hook-form

所以我有一个注册表单react-hook-form,我想禁用它submit input并显示“正在登录...”消息。我已经控制台记录了isSubmitting渲染中的值,并true在我提交时显示,然后false不久之后显示,但是submit button表单中的值永远不会更新以反映isSubmitting状态。

我究竟做错了什么?这是 React Hook Form useFormState 文档

从我看来它应该有效吗?

提前致谢。

import { useState } from "react"
import { useForm, useFormState } from "react-hook-form"
import useAuth from "Hooks/useAuth"

const SignInForm = () => {
  const [firebaseError, setFirebaseError] = useState(null)
  const { signIn } = useAuth()
  const {
    register,
    handleSubmit,
    resetField,
    control,
    formState: { errors },
  } = useForm()

  const { isSubmitting, isValidating } = useFormState({ control })

  const onSubmit = (data) => {
    signIn(data.email, data.password)
      .then((response) => console.log(response))
      .catch((error) => {
        let message = null

        if (error.code === "auth/too-many-requests") {
          message =
            "Too many unsuccessful attempts, please reset password or try again later"
        }

        if (error.code === "auth/wrong-password") {
          message = "Incorrect password, please try again"
        }

        if (error.code === "auth/user-not-found") {
          message = "User does not exist, please try again"
        }

        resetField("password")
        setFirebaseError(message)
      })
  }

  return (
    <form
      className="signupForm"
      onSubmit={handleSubmit(onSubmit)}
      autoComplete="off"
    >
      {console.log(isSubmitting)}
      {firebaseError && (
        <p className="form-top-error has-text-danger">{firebaseError}</p>
      )}

      <div className="field">
        <input
          type="text"
          className="input formInput"
          placeholder="Email"
          {...register("email", {
            required: {
              value: true,
              message: "Field can not be empty",
            },
            pattern: {
              value:
                /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
              message: "Invalid email",
            },
          })}
        />
        {errors.email && (
          <span className="is-block has-text-danger is-size-7">
            {errors.email?.message}
          </span>
        )}
      </div>
      <div className="field">
        <input
          type="password"
          className="input formInput"
          placeholder="Password"
          {...register("password", {
            required: "Field can not be empty",
            minLength: {
              value: 6,
              message: "Must be longer than 6 characters",
            },
          })}
        />
        {errors.password && (
          <span className="is-block has-text-danger is-size-7">
            {errors.password?.message}
          </span>
        )}
      </div>
      <input
        type="submit"
        className="button is-info"
        value={isSubmitting ? "Signing In..." : "Sign In"}
        disabled={isSubmitting}
      />
    </form>
  )
}

export default SignInForm
Run Code Online (Sandbox Code Playgroud)

kno*_*fel 6

我认为您需要重构您的onSubmit函数才能使其在通话期间async保留isSubmitting下来。truesignIn

const onSubmit = async (data) => {
    await signIn(data.email, data.password)
      .then((response) => console.log(response))
      .catch((error) => {
        let message = null

        if (error.code === "auth/too-many-requests") {
          message =
            "Too many unsuccessful attempts, please reset password or try again later"
        }

        if (error.code === "auth/wrong-password") {
          message = "Incorrect password, please try again"
        }

        if (error.code === "auth/user-not-found") {
          message = "User does not exist, please try again"
        }

        resetField("password")
        setFirebaseError(message)
      })
  }
Run Code Online (Sandbox Code Playgroud)

编辑 React Hook 表单 - 异步提交验证(分叉)