![](/img/trans.png)
[英]Enable/disable submit button with react-hook-form in onBlur mode
[英]react-hook-form: Validation not working when using onBlur mode
當用戶選擇超過 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;
您還可以在此處找到該項目的沙箱:
有任何想法嗎?
正如@aadlc 所說,解決方案是將模式設置為onChange
或all
。 我會解釋原因。
來自 react-hook-form API 文檔:
mode: onChange | onBlur | onSubmit | onTouched | all = 'onSubmit'
姓名 | 類型 | 描述 |
---|---|---|
onSubmit(默認) | 細繩 | 驗證將在submit 事件上觸發,無效輸入將附加onChange 事件偵聽器以重新驗證它們。 |
模糊 | 細繩 | 驗證將在blur 事件上觸發。 |
改變 | 細繩 | 驗證將在每個輸入的change 事件上觸發,並導致多次重新渲染。 警告:這通常會對性能產生重大影響。 |
onTouched | 細繩 | 驗證將在第一個blur 事件上觸發。 之后,它將在每個change 事件上觸發。 |
全部 | 細繩 | 驗證將在blur 和change 事件上觸發。 |
在您的代碼中,表單模式為onBlur
。 這意味着驗證是在blur
事件上觸發的(不聚焦輸入)。 當您 select 選項n+1
時,它會從選項n
觸發模糊事件。
例如,就在您 select 第 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
將 valiation 模式更改為all
將在blur
和change
事件中進行驗證,這在此工作流程中可能是多余的,但它也有效。
如果您使用的是受控組件,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}
/>
);
};
或者使用包裝組件:
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}
/>
)}
/>
);
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.