我有一個包含一系列電子郵件的表單。陣列沒有大小限制。我需要檢查陣列中的每個元素是否是有效的電子郵件。用戶應該能夠向陣列添加新元素,并且應該至少有一封電子郵件,每個新元素都應該有一個有效的電子郵件,并且每封電子郵件都應該是唯一的。我希望只有在用戶第一次提交表單后才能進行驗證。驗證電子郵件串列的正確方法應該是什么?
我正在使用 Ant Design 組件并保留無效電子郵件的索引串列,invalidArrayIndexes以便我可以在每個無效行上顯示錯誤。當我添加一個新元素時,我無法獲得所需的訊息(“請輸入您的電子郵件!”),并且當我添加或洗掉新元素時,經過驗證的索引串列變得混亂。我不確定這是否是在 react 中驗證字串串列的正確方法。這是我到目前為止所做的:
import { Button, Form, Input } from "antd";
import { useState } from "react";
const emailRegex = /^[^\s@] @[^\s@] \.[^\s@] $/;
const isValidEmail = (str) => {
return emailRegex.test(str);
};
const MyForm = () => {
const [emails, setEmails] = useState([""]);
const [invalidArrayIndexes, setInvalidArrayIndexes] = useState([]);
const [firstSubmit, setFirstSubmit] = useState(false);
const addEmail = () => {
const updatedEmails = [...emails];
updatedEmails.push("");
setEmails(updatedEmails);
};
const removeEmail = (index) => {
const updatedEmails = [...emails];
updatedEmails.splice(index, 1);
setEmails(updatedEmails);
};
const formSubmitted = () => {
if (!firstSubmit) {
setFirstSubmit(true);
}
const notValidEmails = emails.filter((email) => {
return !isValidEmail(email);
});
const invalidEmailExist = notValidEmails.length > 0;
if (!invalidEmailExist) {
console.log("now submitting");
console.log(emails);
}
};
const valChanged = (e, index) => {
const updatedEmails = [...emails];
updatedEmails[index] = e.target.value;
if (firstSubmit) {
const isValid = isValidEmail(e.target.value);
if (isValid) {
if (invalidArrayIndexes.indexOf(index) > -1) {
const updatedInvalidArrayIndexes = [...invalidArrayIndexes];
updatedInvalidArrayIndexes.splice(
updatedInvalidArrayIndexes.indexOf(index),
1
);
setInvalidArrayIndexes(updatedInvalidArrayIndexes);
}
} else {
if (invalidArrayIndexes.indexOf(index) < 0) {
const updatedInvalidArrayIndexes = [...invalidArrayIndexes];
updatedInvalidArrayIndexes.push(index);
setInvalidArrayIndexes(updatedInvalidArrayIndexes);
}
}
}
setEmails(updatedEmails);
};
const emailList = emails.map((email, index) => {
return (
<Form.Item
key={index}
name="email"
label="email"
rules={[{ required: true, message: "Please enter your email!" }]}
validateStatus={invalidArrayIndexes.includes(index) && "error"}
help={invalidArrayIndexes.includes(index) ? "not a valid email" : " "}
>
<Input
style={{ width: 300 }}
placeholder="enter email"
value={email}
onChange={(e) => valChanged(e, index)}
/>
<Button type="label" onClick={() => removeEmail(index)}>
remove email
</Button>
</Form.Item>
);
});
return (
<div>
{emailList}
<Button type="label" onClick={addEmail}>
add new email
</Button>
<div style={{ marginTop: 20 }}>
<Button type="primary" onClick={formSubmitted}>
send emails
</Button>
</div>
</div>
);
};
export default MyForm;
uj5u.com熱心網友回復:
您看不到所需的錯誤訊息的原因是當您的元素使用Form組件包裝并且提交表單后,ant 設計的驗證規則起作用。但是,這不會解決您的問題,因為這種用法僅支持單個表單項,每個項都具有唯一的name. 我建議您使用 React 表單驗證庫react-validatable-form來驗證您的字串串列,因為它很好地抽象了驗證作業流程和來自 DOM 元素系結的驗證結果。首先,您應該使用 ReactValidatableFormProvider 包裝您的應用程式,例如:
import { ReactValidatableFormProvider } from "react-validatable-form";
import "antd/dist/antd.css";
import MyForm from "./MyForm";
export default function App() {
return (
<ReactValidatableFormProvider>
<MyForm />
</ReactValidatableFormProvider>
);
}
然后你可以使用useValidatableForm帶有listPath類似規則集的鉤子:
import { Button, Form, Input } from "antd";
import { useValidatableForm } from "react-validatable-form";
import get from "lodash.get";
const initialFormData = {
emails: [""]
};
const rules = [
{ listPath: "emails", ruleSet: [{ rule: "required" }, { rule: "email" }] }
];
const MyForm = () => {
const {
isValid,
validationError,
formData,
setPathValue,
setFormIsSubmitted
} = useValidatableForm({
rules,
initialFormData,
hideBeforeSubmit: true
});
const addEmail = () => {
const updatedEmails = get(formData, "emails");
updatedEmails.push("");
setPathValue("emails", updatedEmails);
};
const removeEmail = (index) => {
const updatedEmails = get(formData, "emails");
updatedEmails.splice(index, 1);
setPathValue("emails", updatedEmails);
};
const formSubmitted = () => {
setFormIsSubmitted();
if (isValid) {
console.log("now submitting");
console.log(get(formData, "emails"));
}
};
const emailList = get(formData, "emails").map((email, index) => {
return (
<Form.Item
key={index}
validateStatus={get(validationError, `emails{${index}}`) && "error"}
help={get(validationError, `emails{${index}}`) || " "}
>
<Input
style={{ width: 300 }}
placeholder="enter email"
value={get(formData, `emails[${index}]`)}
onChange={(e) => setPathValue(`emails[${index}]`, e.target.value)}
/>
<Button type="label" onClick={() => removeEmail(index)}>
remove email
</Button>
</Form.Item>
);
});
return (
<div>
{emailList}
<Button type="label" onClick={addEmail}>
add new email
</Button>
<div style={{ marginTop: 20 }}>
<Button type="primary" onClick={formSubmitted}>
send emails
</Button>
</div>
</div>
);
};
export default MyForm;
您可以查看此沙箱以獲取實時作業示例。
uj5u.com熱心網友回復:
我建議使用類似于 yup 的庫。是的,您可以為表單定義模式,如下所示:
const RegisterUserValidationSchema = yup.object().shape({
name: yup.string()
.min(2, "No way,too short!")
.max(200, "So long,are you serious?")
.required("Required"),
email: yup.string().email("Please enter an email").required("Required"),
password: yup.string().required("Password is required"),
confirmPassword: yup.string()
.oneOf([yup.ref('password'), null], "Passwords must match"),
phoneNumber: yup.number("Please enter a valid phone number"),
})
然后,您可以將您的值與您的架構進行比較
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/347466.html
