React-Hook-Form v7:禁用字段时如何跳过Controller组件验证
问题描述
我正在使用react-hook-form搭配@mui/material开发,需要将MUI的TextField组件通过render属性传入react-hook-form的Controller组件中。
我期望当TextField处于禁用状态时,该字段的验证规则能自动跳过,但目前无论是否禁用,验证都会触发,导致禁用字段显示错误提示。
不使用Controller、直接用register时,<input {...register('someField', {disabled: true})}/>可以正常跳过验证,但我需要在使用Controller组件的场景下实现同样效果。
已尝试方案
- 仅为字段添加disabled属性
<Controller name="secondField" control={control} shouldUnregister={true} //rules={{required:true}} render={({ field: { onChange, value, ref }, fieldState: { error }, formState }) => { console.log(error); let commonFieldVal = watch("commonTextField"); //let isDisabled = commonFieldVal === "bob"; return ( <TextField label="secondField" disabled={true} error={!!error} value={value} onChange={onChange} ref={ref} />
- 为字段添加shouldUnregister属性
完整代码示例
import { useForm, Controller, ControllerFieldState, ControllerRenderProps, FieldValues, UseFormStateReturn } from "react-hook-form"; import { TextField, Button, Box } from "@mui/material"; import { useEffect, useState } from "react"; import { yupResolver } from "@hookform/resolvers/yup"; import * as yup from "yup"; let CommonTextField = ({ error, value, onChange, setSecondFormState }) => { let isDisabled = value === "bob"; useEffect(() => { setSecondFormState(isDisabled); }, [isDisabled]); return ( <TextField label="commonTextField" error={!!error} value={value} onChange={onChange} /> ); }; ///////////////////////////////// const schema = yup.object({ commonTextField: yup.string().required("commonTextField is required"), secondField: yup.string().required("secondField is required") }); ///////////////////////////////// export default function App() { ///////////////////////////// // useForm let { handleSubmit, watch, reset, formState, setValue, control, getValues, getFieldState, register, unregister } = useForm({ defaultValues: { commonTextField: "", secondField: "" }, shouldUnregister: true, resolver: yupResolver(schema) }); let { errors } = formState; let [secondFormIsDisabled, setSecondFormState] = useState(false); console.log(errors); return ( <form onSubmit={handleSubmit((data) => { console.log("Succes Submit FORM DATA----->> ", data); reset(); })} > <Box sx={{ display: "flex", flexDirection: "column", gap: "10px" }}> <Controller name="commonTextField" control={control} render={({ field: { onChange, value }, fieldState: { error }, formState }) => { console.log(error); return ( <CommonTextField error={!!error} value={value} onChange={onChange} setSecondFormState={setSecondFormState} /> ); }} /> {!secondFormIsDisabled && ( <Controller name="secondField" control={control} shouldUnregister={true} //rules={{required:true}} render={({ field: { onChange, value, ref }, fieldState: { error }, formState }) => { console.log(error); let commonFieldVal = watch("commonTextField"); //let isDisabled = commonFieldVal === "bob"; return ( <TextField label="secondField" disabled={secondFormIsDisabled} error={!!error} value={value} onChange={onChange} ref={ref} /> ); }} /> )} </Box> <Button type="submit">SUBMIT</Button> </form> ); }
临时解决办法
移除Yup验证,将验证规则转移到react-hook-form的rules中,当需要显示禁用字段时,通过条件渲染区分:
{!secondFormIsDisabled ? ( <Controller name="secondField" control={control} shouldUnregister={true} rules={{required:true, ...secondFieldValidation}} render={({ field: { onChange, value, ref }, fieldState: { error }, formState }) => { console.log(error); //let commonFieldVal = watch("commonTextField"); //let isDisabled = commonFieldVal === "bob"; return ( <TextField label="secondField" error={!!error} value={value} onChange={onChange} ref={ref} /> ); }} /> ): <TextField disabled={secondFormIsDisabled} />}
内容的提问来源于stack exchange,提问作者scad scad
相关产品推荐
相关产品推荐

