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

当用户选择超过 5 个复选框但未成功时,我尝试使用 yup 和 react-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"...,您将同时获得onChanage 和onBlur 的行为

标签: reactjs material-ui yup react-hook-form


【解决方案1】:

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

来自 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 将同时验证 blur 和 change 事件,这在此工作流程中可能是多余的,但它也有效。

【讨论】:

    猜你喜欢
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-23
    相关资源
    最近更新 更多