我有一个使用react hooks- form的表单,我为我做了一些组件,比如文本框、文本区域、选择、.这些都是被控制的部件。现在,在我的表单中,我使用Yup进行验证,并且有一点是不起作用的。在我的表单中,我有一个动态输入类型(queryParam),它根据组select的值进行更改,它可以是文本框,也可以是select。当组为1时,不需要queryParam,但是如果组的值大于1,则显示字段,我需要queryParam输入的值,但这不是验证,我不能按按钮。queryParam可以是文本框中的文本,也可以是从select中作为字符串的数字。
我的验证模式:
import * as Yup from "yup";
export const validationSchema = Yup.object().shape
({
text: Yup
.string()
.required()
.max(2048, "Az üzenet szövege túl hosszú,"),
groupID: Yup
.number()
.required(),
queryParam: Yup
.string()
.when("groupID",
{
/*** THIS PART NOT WORKING ***/
is: (groupID: number) => groupID > 1,
then: Yup.mixed()
.required("Kötelező mező.")
}),
isVoteType: Yup
.boolean(),
positiveAnswer: Yup
.string()
.when("isVoteType",
{
is: (isVoteType: boolean) => isVoteType,
then: Yup.string()
.required("Kötelező mező.")
}),
negativeAnswer: Yup
.string()
.when("isVoteType",
{
is: (isVoteType: boolean) => isVoteType,
then: Yup.string()
.required("Kötelező mező.")
})
});我的组件和表格:
import React, { useEffect, useState } from "react";
import { IonButton, IonCol, IonContent, IonGrid, IonPage, IonRow } from "@ionic/react";
import Footer from "src/pages/shared/footer/footer";
import Header from "src/pages/shared/header/header";
import { IMessageRequest } from "./../../../../modell/request/IMessageRequest";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/dist/yup";
import { validationSchema } from "./validation";
import { GroupsSelectList } from "./../../../../pages/shared/selectLists/GroupsSelectList";
import { ISelectListItem } from "./../../../../modell/common/ISelectListItem";
import HookFormTextArea from "./../../../../library/HookForm/Components/hookFomTextArea";
import { WebAPI } from "src/service/webAPI";
import HookFormCheckbox from "./../../../../library/HookForm/Components/hookFormCheckbox";
import HookFormTextBox from "./../../../../library/HookForm/Components/hookFomTextBox";
import { DegreeSelectList } from "./../../../../pages/shared/selectLists/DegreeSelectList";
import { SexesSelectList } from "./../../../../pages/shared/selectLists/SexesSelectList";
import { CountriesSelectList } from "src/pages/shared/selectLists/CountriesSelectList";
const NewMessagePage: React.FC = () =>
{
const[groups, setGroups] = useState<ISelectListItem[]>([]);
const[selectedGroup, setSelectedGroup] = useState<ISelectListItem>();
const[degrees, setDegrees] = useState<ISelectListItem[]>([]);
const[sexes, setSexes] = useState<ISelectListItem[]>([]);
const[countries, setCountries] = useState<ISelectListItem[]>([]);
const[isVote, setIsVote] = useState<boolean>(false);
useEffect(() =>
{
const fetch = async (): Promise<void> =>
{
await WebAPI.Common.groups()
.then( (data: ISelectListItem[]) => setGroups(data));
await WebAPI.Common.degrees()
.then( (data: ISelectListItem[]) => setDegrees(data));
await WebAPI.Common.sexes()
.then( (data: ISelectListItem[]) => setSexes(data));
await WebAPI.Common.countries()
.then( (data: ISelectListItem[]) => setCountries(data));
}
fetch();
}, []);
const { control, handleSubmit, errors, register, formState } = useForm<IMessageRequest>
({
mode: "onChange",
resolver: yupResolver(validationSchema)
});
const onSubmit = async (data: IMessageRequest): Promise<void> =>
{
data.negativeAnswer = data.negativeAnswer === "" ? undefined : data.negativeAnswer;
data.positiveAnswer = data.positiveAnswer === "" ? undefined : data.positiveAnswer;
console.log({...data});
}
const QueryParamElement = (): JSX.Element | null =>
{
switch (selectedGroup?.id)
{
/* country */
case 2:
return <CountriesSelectList
name="queryParam"
label="Cél ország neve"
data={countries}
placeholder="Kérem válasszon"
displayMember={(item: ISelectListItem) => item.name}
valueMember={(item: ISelectListItem) => item?.id.toString()}
control={control}
errors={errors} />
/* city */
case 3:
return <HookFormTextBox
name="queryParam"
label="Cél város neve"
type="text"
control={control}
errors={errors} />;
/* degree */
case 4:
return <DegreeSelectList
name="queryParam"
label="Válassza ki az iskola végzettséget"
data={degrees}
placeholder="Kérem válasszon"
displayMember={(item: ISelectListItem) => item.name}
valueMember={(item: ISelectListItem) => item?.id.toString()}
control={control}
errors={errors}
reference={register} />;
/* sex */
case 5:
return <SexesSelectList
name="queryParam"
label="Válassza ki a nemet"
data={sexes}
placeholder="Kérem válasszon"
displayMember={(item: ISelectListItem) => item.name}
valueMember={(item: ISelectListItem) => item?.id.toString()}
control={control}
errors={errors}
reference={register} />;
default: return null;
}
}
return (
<IonPage>
<Header text="Új Üzenet Létrehozása" />
<IonContent fullscreen>
<form onSubmit={handleSubmit((data: IMessageRequest) => onSubmit(data))}>
<IonGrid>
<IonRow>
<IonCol size="12" sizeMd={QueryParamElement() === null ? "12" : "6"}>
<GroupsSelectList
name="groupID"
label="Csoport"
data={groups}
placeholder="Kérem válasszon"
displayMember={(item: ISelectListItem) => item.name}
valueMember={(item: ISelectListItem) => item?.id.toString()}
onChange={ (item: ISelectListItem) => setSelectedGroup(item)}
control={control}
errors={errors}
reference={register} />
</IonCol>
<IonCol size="12" sizeMd="6">
{QueryParamElement()}
</IonCol>
</IonRow>
<IonRow>
<HookFormTextArea
name="text"
label="Üzenet szövege"
autoGrow={true}
fullWidth={true}
control={control}
errors={errors} />
</IonRow>
<IonRow>
<IonCol size="12" sizeMd="4">
<HookFormCheckbox
name="isVote"
label="Szavazás"
onChange={(e: boolean) =>
{
setIsVote(e);
console.log(e);
}}
checked={isVote}
control={control}
errors={errors} />
</IonCol>
<IonCol size="12" sizeMd="4">
<HookFormTextBox
name="positiveAnswer"
label="Pozitív válasz szövege"
type="text"
disabled={!isVote}
control={control}
errors={errors} />
</IonCol>
<IonCol size="12" sizeMd="4">
<HookFormTextBox
name="negativeAnswer"
label="Negatív válasz szövege"
type="text"
disabled={!isVote}
control={control}
errors={errors} />
</IonCol>
</IonRow>
<IonRow>
</IonRow>
<IonRow>
<IonCol>
<IonButton expand="block" type="submit" className="ion-margin-top"
disabled={formState.isValid === false}>
KÜLDÉS
</IonButton>
</IonCol>
</IonRow>
</IonGrid>
</form>
</IonContent>
<Footer />
</IonPage>
);
}
export default NewMessagePage;发布于 2021-02-08 11:21:38
以下是我最后所做的:
import * as Yup from "yup";
export const validationSchema = Yup.object().shape
({
text: Yup
.string()
.required("Kötelező mező.")
.max(2048, "Az üzenet szövege túl hosszú,"),
groupID: Yup
.number()
.min(1, "Kötelező mező.")
.required("Kötelező mező."),
queryParam: Yup
.mixed()
.when("groupID",
{
is: (groupID: number) => groupID > 1,
then: Yup.lazy( (value: any) =>
{
console.log("value: ", value);
if (value === -1 || value === "-1" || value === "" || value === undefined || value === null)
{
switch (typeof(value))
{
case "string": return Yup.string()
.required("Kötelező mező.");
case "number": return Yup.number()
.min(1, "Kötelező mező.");
}
}
return Yup.mixed()
.notRequired()
})
}),
isVoteType: Yup
.boolean(),
positiveAnswer: Yup
.string()
.when("isVoteType",
{
is: (isVoteType: boolean) => isVoteType,
then: Yup.string()
.required("Kötelező mező.")
}),
negativeAnswer: Yup
.string()
.when("isVoteType",
{
is: (isVoteType: boolean) => isVoteType,
then: Yup.string()
.required("Kötelező mező.")
})
});发布于 2022-07-13 04:07:28
尝试使用transform()。当value是一个空字符串时,它帮助我解决了这个问题。
yup.mixed().transform((v) => (!v ? undefined : v)).required('Field is required')https://stackoverflow.com/questions/66099657
复制相似问题