问题描述
const MyTextInput = ({ label,...props }) => {
const [field,Meta] = useField(props);
return (
<>
<label htmlFor={props.id || props.name}>
{label} <span>*</span>
</label>
<div>
<input {...field} {...props} />
</div>
{Meta.touched && Meta.error ? <div>{Meta.error}</div> : null}
</>
);
};
const MyCheckBox = ({ children,Meta] = useField({ ...props,type: "checkBox" });
return (
<div>
<label>
<input type="checkBox" {...field} {...props} />
<span> {children}</span>
</label>
{Meta.touched && Meta.error ? (
<div>{Meta.error}</div>
) : null}
</div>
);
};
我正在使用这些组件为我的表单创建输入:
<MyTextInput
label="validity"
name="validity"
type="date"
disabled={a}
/>
<MyCheckBox name="withoutLimitations" onClick={checkMe}>
without Limitation
</MyCheckBox>
<MyTextInput
label="number Of Uses "
name="numberOfUses"
type="text"
disabled={b}
/>
<MyCheckBox name="withoutLimitations_1" onClick={checkMe1}>
without Limitation
</MyCheckBox>
我也使用 Yup 来创建验证:
validationSchema={Yup.object({
validity: Yup.date().required(),numberOfUses: Yup.number().required()
})}
现在我的问题是当我选中一个复选框时如何更改我的验证架构。
例如,如果我选中第一个复选框,这意味着日期表单应该被禁用并且值应该变为空值,没有用户在选中复选框之前选择什么。
使用 useState 我可以有条件地启用或禁用输入,但不能更改验证架构,因为当输入没有任何数据时,我按下提交按钮时什么也没有发生。
请帮我解决这个问题
解决方法
我会这样解决:
const validationSchema = Yup.object({
validity: a ? Yup.date() : Yup.date().required(),numberOfUses: b ? Yup.number() : Yup.number().required()
})
并将其放入Formik
:
validationSchema={validationSchema}
或者您也可以改进它,使用 useMemo
减少组件的重新渲染:
const validationSchema2 = React.useMemo(
() =>
Yup.object({
validity: a ? Yup.date() : Yup.date().required(),numberOfUses: b ? Yup.number() : Yup.number().required(),}),[a,b],)
,
经过研究,我找到了答案。这是仅第一个输入和复选框的示例
withoutLimitations: Yup.boolean(),validity: Yup.date().when("withoutLimitations",{
is: false,then: Yup.date().required(),
我还更改了日期输入,因为 safari 不支持 <input type="date" />
。
现在它看起来像这样:
const [check,setCheck] = useState(false);
<MuiPickersUtilsProvider
utils={DateFnsUtils}
locale={ruLocale}
>
<KeyboardDatePicker
format="MM/dd/yyyy"
value={check ? null : beforeDate}
onChange={(value) => {
formProps.setFieldValue("validity",value);
setBeforeDate(value);
}}
autoOk={true}
/>