【问题标题】:Yup & React Hook Form: How to validate onChange rather than onSubmitYup & React Hook Form:如何验证 onChange 而不是 onSubmit
【发布时间】:2021-10-05 23:01:42
【问题描述】:

我有一个 onChange 函数 onNameChange,其中包含一个 valid 变量,该变量应该与名称字段的 yup 验证相匹配。问题是有效变量似乎仅在提交表单后才正确,而不是在更改名称字段时;我希望这在必须提交之前有效。

如何在更改名称字段而不是提交时使值正确?请注意,我发现了一个类似的帖子,但它使用了 Formik,这不是我想要使用的:Formik + Yup: How to immediately validate form before submit?

Yup 设置:

const schema = Yup.object().shape({
    name: Yup.string()
      .required("Required")
      .min(3, "Enter at least 3 characters")
  });
  const {
    register,
    handleSubmit,
    setError,
    formState: { errors },
    trigger
  } = useForm({
    resolver: yupResolver(schema)
    // mode: "onTouched",
    // reValidateMode: "onChange"
  });

改名功能:

  const onNameChange = async ({ target: { value } }) => {
    const valid = await trigger("name");
    console.log("valid", valid, "value", value);
    if (!valid) {
      // @todo: bug here? valid only correct after submitting
      return;
    }
    getPokemon(value);
    setShowPokemon(false);
  };

演示表格:

<form onSubmit={handleSubmit(onSubmit /*, onError*/)}>
        <input
          {...register("name", { required: true })}
          name="name"
          placeholder="Enter a pokemon"
          onChange={onNameChange}
        />
        <button type="submit" onClick={onSubmit}>
          Show Pokemon
        </button>
        {errors.name && <p>{errors.name.message}</p>}
      </form>

我在代码沙盒上做了一个现场演示,应该会有所帮助:

https://codesandbox.io/s/react-playground-forked-odwi2?file=/Pokemon.js

谢谢

【问题讨论】:

    标签: javascript yup react-hook-form


    【解决方案1】:

    问题是您在更改名称 &lt;input /&gt; 后没有更新 RHF 状态,因为您正在覆盖从 {...register('name')} 返回的 onChange 属性。

    所以基本上你必须在这里选择:

    1. 使用setValueonNameChange 回调中更新name 的RHF 状态值
    2. 使用&lt;Controller /&gt;组件

    您可以在 GitHub 上的 discussion 中了解它。

    这将如何使用&lt;Controller /&gt; 实现第二个选项:

    <form onSubmit={handleSubmit(onSubmit /*, onError*/)}>
      <Controller
        name="name"
        control={control}
        defaultValue=""
        render={({ field: { value, onChange, ...field } }) => (
          <input
            {...field}
            onChange={({ target: { value } }) => {
              onChange(value);
              onNameChange(value);
            }}
            placeholder="Enter a pokemon"
          />
        )}
      />
    
      <button type="submit" onClick={onSubmit}>
        Show Pokemon
      </button>
      {errors.name && <p>{errors.name.message}</p>}
    </form>
    

    【讨论】:

    • 这是一个非常有用的解释,谢谢。使用 watch 记录输入也证明你是对的
    猜你喜欢
    • 2021-11-05
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2022-08-12
    • 1970-01-01
    相关资源
    最近更新 更多