react-hook-form:使用 onBlur 模式时验证不起作用

Posted

技术标签:

【中文标题】react-hook-form:使用 onBlur 模式时验证不起作用【英文标题】:react-hook-form: Validation not working when using onBlur mode 【发布时间】:2021-06-19 20:29:28 【问题描述】:

当用户选择超过 5 个复选框但未成功时,我尝试使用 yupreact-hook-form 显示错误。

相反,选择了第七个复选框时显示了错误。

这是简化的代码:

imports...

const schema = yup.object().shape(
  option: yup.array().max(5)
);
function App() 
  const  register, handleSubmit, errors  = useForm(
    mode: "onBlur",
    resolver: yupResolver(schema)
  );

  const [state, setState] = useState(
    wasSubmitted: false
  );

  const submit = async (data) => 
    window.alert(JSON.stringify(data));
  ;

  if (state.wasSubmitted) 
    return <p>Congrats</p>;
   else 
    return (
      <>
        <CssBaseline />
        <Container maxWidth="sm">
          <Typography variant="h2" component="h1">
            My form
          </Typography>
          <form noValidate autoComplete="off" onSubmit=handleSubmit(submit)>
            <FormControl
              component="fieldset"
              error=!!errors.option
            >
              <FormLabel component="legend">
                Please select the category or categories of books the child is
                interested in:
              </FormLabel>
              <FormGroup>
                <FormControlLabel
                  control=<Checkbox name="option" inputRef=register />
                  value="Option1"
                  label="Option 1"
                />
                <FormControlLabel
                  control=<Checkbox name="option" inputRef=register />
                  value="Option2"
                  label="Option 2"
                />
                <FormControlLabel
                  control=<Checkbox name="option" inputRef=register />
                  label="Option3"
                  value="Option 3"
                />
                <FormControlLabel
                  control=<Checkbox name="option" inputRef=register />
                  value="Option4"
                  label="Option 4"
                />
                <FormControlLabel
                  control=<Checkbox name="option" inputRef=register />
                  value="Option5"
                  label="Option 5"
                />
                <FormControlLabel
                  control=<Checkbox name="option" inputRef=register />
                  value="Option6"
                  label="Option 6"
                />
                <FormControlLabel
                  control=<Checkbox name="option" inputRef=register />
                  value="Option7"
                  label="Option 7"
                />
                <FormControlLabel
                  control=<Checkbox name="option" inputRef=register />
                  value="Option8"
                  label="Option 8"
                />
                <FormControlLabel
              <FormHelperText>Up to five categories</FormHelperText>
            </FormControl>

            <Button
              type="submit"
              disableElevation
            >
              Submit
            </Button>
          </form>
        </Container>
      </>
    );
  


export default App;

您也可以在这里找到项目的沙箱:

有什么想法吗?

【问题讨论】:

useForm的模式改为onChange:useForm( mode: "onChange", ... 谢谢!解决了这个问题。另外,我刚刚意识到,如果您将useForm 的模式更改为useForm( mode: "all"...,您将同时获得onChanageonBlur 的行为 【参考方案1】:

正如@aadlc 所说,解决方案是将模式设置为onChangeall。我会解释原因。

来自 react-hook-form API docs:

mode: onChange | onBlur | onSubmit | onTouched | all = 'onSubmit'

Name Type Description
onSubmit (Default) string Validation will trigger on the submit event and invalid inputs will attach onChange event listeners to re-validate them.
onBlur string Validation will trigger on the blur event.
onChange string Validation will trigger on the change event with each input, and lead to multiple re-renders. Warning: this often comes with a significant impact on performance.
onTouched string Validation will trigger on the first blur event. After that, it will trigger on every change event.
all string Validation will trigger on the blur and change events.

在您的代码中,表单模式为onBlur。这意味着验证是在blur 事件上触发的(不聚焦输入)。当您选择选项n+1 时,它会从选项n 触发模糊事件。

例如就在您选择第 6 个选项(无效)之前,blur 事件从第 5 个选项(有效)触发,因为您不再关注它,并从选项 1-5 进行验证,因此您必须检查第 7 个选项以重新验证从 1 到 6 的选项。

-- select up to 5 options --
select option 4

blur event fires from option 4 -> validate -> pass
select option 5

blur event fires from option 5 -> validate -> pass
select option 6

blur event fires from option 6 -> validate -> fail
select option 7

将验证模式更改为onChange 将验证 change 事件触发后,所有值都是最新的:

-- select up to 5 options --
select option 4

blur event fires from option 4
select option 5
change event fires from option 5 -> validate -> pass

blur event fires from option 5
select option 6
change event fires from option 6 -> validate -> fail

blur event fires from option 6
select option 7
change event fires from option 7 -> validate -> fail

将验证模式更改为 all 将同时验证 blurchange 事件,这在此工作流程中可能是多余的,但它也有效。

【讨论】:

以上是关于react-hook-form:使用 onBlur 模式时验证不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用 React-Hook-Form 和 YupResolver 时遇到此错误:尝试导入错误:“set”未从“react-hook-form”导出(导入为“o”)

如何使用 react-hook-form 有条件地禁用提交按钮?

react-hook-form使用

使用 reactstrap 从 react-hook-form 访问错误

使用 Yup 的 react-hook-form 解析器类型错误

react-hook-form 使用重置选择下拉值