简体   繁体   English

是的 & React Hook Form:如何验证 onChange 而不是 onSubmit

[英]Yup & React Hook Form: How to validate onChange rather than onSubmit

I have an onChange function onNameChange that contains a valid variable that should match the yup validation of the name field.我有一个 onChange 函数onNameChange ,它包含一个valid变量,该变量应该与 name 字段的 yup 验证相匹配。 The problem is that the valid variable only seems to be correct after submitting the form, not on changing the name field;问题是有效变量似乎只有在提交表单后才正确,而不是在更改名称字段时; I want this to be valid before having to submit.我希望在必须提交之前这是有效的。

How can I get the value to be correct on changing the name field rather than submitting?如何在更改名称字段而不是提交时获得正确的值? Note that I found a similar post but that uses Formik, which is not what I want to use: Formik + Yup: How to immediately validate form before submit?请注意,我发现了一个类似的帖子,但它使用了 Formik,这不是我想要使用的: Formik + 是的:如何在提交前立即验证表单?

The Yup settings:是的设置:

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"
  });

The name changing function:改名功能:

  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);
  };

The demo form:演示形式:

<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>

I've made a live demo on codesandbox that should be helpful:我在 codeandbox 上做了一个现场演示,应该会有所帮助:

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

Thanks谢谢

The problem is that you aren't updating the RHF state after changing your name <input /> , because you are overriding the onChange prop, which is returned from {...register('name')} .问题是您在更改名称后没有更新 RHF 状态<input /> ,因为您覆盖了从{...register('name')}返回的onChange道具。

So basically you have to options here:所以基本上你必须在这里选择:

  1. use setValue to update the RHF state value for name inside your onNameChange callback使用setValue更新onNameChange回调中name的 RHF 状态值
  2. use <Controller /> component使用<Controller />组件

You can read about it in this discussion on GitHub.你可以在 GitHub 上的这个讨论中阅读它。

This how it would be implemented for the second option using <Controller /> :这将如何使用<Controller />为第二个选项实现:

<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>

编辑 React PlayGround(分叉)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM