aad*_*dlc 5 reactjs material-ui yup react-hook-form
我想用显示错误yup,并react-hook-form当用户选择超过5个复选框没有成功。
相反,选择第七个复选框时会显示错误。
这是简化的代码:
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;
Run Code Online (Sandbox Code Playgroud)
您还可以在此处找到项目的沙箱:
有任何想法吗?
Nea*_*arl 41
正如@aadlc所说,解决方案是将模式设置为onChange或all。我会解释原因。
来自react-hook-form API文档:
mode: onChange | onBlur | onSubmit | onTouched | all = 'onSubmit'
| 姓名 | 类型 | 描述 |
|---|---|---|
| 提交时(默认) | 细绳 | 验证将在事件上触发submit,无效输入将附加onChange事件侦听器以重新验证它们。 |
| 模糊 | 细绳 | 验证将在事件上触发blur。 |
| 改变时 | 细绳 | 验证将在每个输入的事件上触发change,并导致多次重新渲染。警告:这通常会对性能产生重大影响。 |
| 触摸时 | 细绳 | 验证将在第一个事件时触发blur。之后,它将在每个change事件上触发。 |
| 全部 | 细绳 | blur验证将在和事件上触发change。 |
在您的代码中,表单模式是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
Run Code Online (Sandbox Code Playgroud)
将验证模式更改为将在事件触发后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
Run Code Online (Sandbox Code Playgroud)
将验证模式更改为all将同时验证 inblur和changeevents,这在此工作流程中可能有点过分,但它也有效。
小智 9
如果您使用受控组件,onBlur 可能不会自动触发。您必须手动连接它:
export const MyControlledField = ({ fieldName }: { fieldName: string }) => {
const methods = useFormContext();
const value = useWatch({ name: fieldName });
const controller = useController({
name: fieldName,
control: methods.control,
});
return (
<TextField
value={value ?? ''}
onChange={(e) => {
methods.setValue(fieldName, e.target.value);
}}
onBlur={controller.field.onBlur}
/>
);
};
Run Code Online (Sandbox Code Playgroud)
或者使用包装的组件:
export const MyWrappedField = ({ fieldName }: { fieldName: string }) => {
const methods = useFormContext();
return (
<Controller
control={methods.control}
name={fieldName}
render={({ field: { onChange, onBlur, value, name, ref }, fieldState, formState }) => (
<TextField
onBlur={onBlur}
onChange={onChange}
value={value}
inputRef={ref}
/>
)}
/>
);
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5108 次 |
| 最近记录: |