问题描述
我想要的是要么填写 IT 主管联系人中的所有字段,要么不填写任何字段。因此,例如,如果在 IT 主管联系人对象中填写了名字、姓氏字段并且未填写电子邮件、电话号码,那么将显示错误消息:“您应该填写 IT 主管联系人中的所有字段或不填写任何字段”。如果 IT 主管联系人中的所有字段都已填写或未填写,则不会显示任何错误消息。可以用 yup 实现吗?我将在图片下方提供代码
这是将被发送到后端的对象的最终接口:
interface Contact{
firstName: string;
lastName: string;
email: string;
phone: string;
}
export interface ICompanyCreation {
name: string;
status: Status;
country: string;
city: string;
address: string;
zipCode: number;
admin: Contact;
itHead: Contact;
customerManager: Contact;
}
这是我的验证架构:
export const validationSchema = yup.object().shape({
name: yup.string().matches(nameRegEx,nameMessage).required(requiredMessage).trim(),country: yup.string().matches(countryRegEx,countryMessage).required(requiredMessage).trim(),city: yup.string().matches(nameRegEx,address: yup.string().required(requiredMessage).trim(),zipCode: yup.number().positive(positiveNumberMessage).integer(integerNumberMessage).required(requiredMessage).typeError(numberMessage),admin: object().shape(
{
firstName: yup.string().matches(nameRegEx,lastName: yup.string().matches(nameRegEx,phone: yup.string().matches(phoneRegEx,phonemessage).required(requiredMessage).trim(),email: yup.string().email(emailMessage).required(requiredMessage).trim(),}
),itHead: object().shape(
{
firstName: yup.string().matches(nameRegEx,customerManager: object().shape(
{
firstName: yup.string().matches(nameRegEx,});
解决方法
您可以拥有如下所示的 itHead
验证架构。这个想法是检查除自身之外的任何字段是否具有某些值。如果是这样,那么该字段本身也将被标记为必填。
请注意,传递普通函数而不是箭头函数可以让您访问siblings属性.另请注意,我已将 nameRegEx
用于所有字段,因此请将其替换为相应的正则表达式。
itHead: Yup.object().shape({
firstName: Yup.string().test(
"first-name-test","Please provide last name",function (value) {
const { lastName,phone,email } = this.parent;
if (lastName || phone || email) {
return value && nameRegEx.test(value);
}
return true;
}
),lastName: Yup.string()
.trim()
.test("last-name-test",function (value) {
const { firstName,email } = this.parent;
if (firstName || phone || email) {
return value && nameRegEx.test(value);
}
return true;
}),phone: Yup.string().test(
"phone-test","Please provide phone",lastName,email } = this.parent;
if (firstName || lastName || email) {
return value && nameRegEx.test(value);
}
return true;
}
),email: Yup.string().test(
"email-test","Please provide email",lastName } = this.parent;
if (firstName || phone || lastName) {
return value && nameRegEx.test(value);
}
return true;
}
)
})
,
使用 when 实现它的替代方法:
import Link from 'next/link';
import React,{ useState } from 'react';
import { listSearchPvt } from '../../actions/privateJob';
const SearchPvt = () => {
const [values,setValues] = useState({
search: undefined,results: [],searched: false,message: '',});
const { search,results,searched,message,} = values;
const searchSubmit = e => {
e.preventDefault();
listSearchPvt({ search }).then(data => {
setValues({ ...values,results: data,searched: true,message: `${data.length} jobs found` });
});
};
const handleChange = e => {
setValues({ ...values,search: e.target.value,results: [] });
};
const searchedJobs = (results = []) => {
return (
<div className="bg-light">
{message && <p className="extra-small text-light-gray " >{message}</p>}
{results.map((privateJob,i) => {
return (
<div key={i} >
<Link href={`/privateJobs/${privateJob.slug}`}>
<a>
<h3 className="text-dark " style={{fontFamily:`'Source Serif Pro',serif`,lineHeight:'1.9rem'}}>
?<span> </span>{privateJob.title}
</h3>
<div className="line"></div>
</a>
</Link>
</div>
);
})}
</div>
);
};
const searchForm = () => (
<form onSubmit={searchSubmit} style={{width: '100%',display: 'flex',alignItems:'end',height: '2.4rem',justifyContent:'space-between',alignContent:'center',alignItems:'center' }} className="btn nbtn btn-success" >
<input className='btn nbtn btn-success' style={{width:'100%'}} type="search" placeholder="Search Jobs" onChange={handleChange} />
<button className="btn nbtn btn-dark lead my-1" type="submit" >Search</button>
</form>
);
return (
<>
<div style={{display:'block'}}>
<div className="my-3">{searchForm()}</div>
{searched && <div className='blog m-2 ' >{searchedJobs(results)}</div>}
</div>
</>
);
}
export default SearchPvt;