问题
I am building a form a where a user can store multiple phone numbers and set the privacy of that number (whether he wants the number to be publicly displayed or not).
I have succesfully created the form but stuck in formik-yup validation and getting the values (phone number with privacy value) to further send it to backend.
import React, { Component } from "react";
import { Formik, Form, Field, ErrorMessage, FieldArray } from "formik";
import * as Yup from "yup";
import DropDown from "./DropDown";
const phoneNumberPrivacyDropdown = [
{ value: "private", option: "Private" },
{ value: "public", option: "Public" }
];
const phoneRegExp = /^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/; // for Mobile Numbers
export default class PhoneNumbers extends Component {
constructor(props) {
super(props);
this.state = {
phoneNumbers: [{ privacy: "", number: "" }]
};
this.addNewPhoneNumber = this.addNewPhoneNumber.bind(this);
this.removePhoneNumber = this.removePhoneNumber.bind(this);
}
addNewPhoneNumber() {
let newPhoneNumber = { privacy: "", number: "" };
this.setState({
phoneNumbers: [...this.state.phoneNumbers, newPhoneNumber]
});
}
removePhoneNumber = key => {
let phoneNumbers = this.state.phoneNumbers;
phoneNumbers.splice(key, 1);
this.setState({
phoneNumbers: phoneNumbers
});
};
render() {
return (
<div>
<h1 className="form-subHead">Multiple Phone Numbers.</h1>
<Formik
initialValues={{
phoneNumbers: this.state.phoneNumbers
}}
validationSchema={Yup.object().shape({
phoneNumbers: Yup.array().of(
Yup.object().shape({
mobile: Yup.string()
.required("Please tell us your mobile number.")
.length(10, "Please enter a valid mobile number.")
.matches(phoneRegExp, "Please enter a valid mobile number.")
})
)
})}
onSubmit={(values, { resetForm, setErrors, setSubmitting }) => {
setTimeout(() => {
console.log("Getting form values - ", values);
setSubmitting(false);
}, 500);
}}
enableReinitialize={true}
>
{props => {
const {
values,
touched,
dirty,
errors,
isSubmitting,
handleChange,
handleBlur,
setFieldValue,
setFieldTouched
} = props;
return (
<Form id="signUpForm" className="signinupForm mt-4" noValidate>
<div className="formSection">
<div className="row form-row">
<div className="col-sm-6">
<div className="form-group phoneNumberGroup">
<label htmlFor="phoneNumbers" className="form-label">
Phone Number
</label>
{this.state.phoneNumbers.map((phoneNumber, i) => (
<div className="phoneNumber" key={i}>
<Field
type="number"
name={`phone${i + 1}`}
placeholder="Contact Number"
className="form-control mobileNumber"
/>
<div className="selectPhonePrivacy">
<DropDown
items={phoneNumberPrivacyDropdown}
inputname="phonePrivacy"
showIconOnly={false}
/>
</div>
{i != 0 && (
<span
className="modifyInput removeElement"
onClick={() => this.removePhoneNumber({ i })}
>
-
</span>
)}
<ErrorMessage
name="mobile"
component="span"
className="invalid-input"
/>
</div>
))}
{this.state.phoneNumbers.length <= 2 && ( // only upto 3 phone numbers allowed!
<a
className="modifyInput addElement"
onClick={this.addNewPhoneNumber}
>
Add Another Phone
</a>
)}
</div>
{/* Phone Numbers Group */}
</div>
</div>
</div>
<div className="text-center">
<button
type="submit"
className="btn btn-filled"
disabled={!dirty || isSubmitting}
>
Finish
</button>
{/*Submit */}
</div>
</Form>
);
}}
</Formik>
</div>
);
}
}
Here is a codesandbox demo for the actual codes - https://codesandbox.io/s/dynamic-field-validation-7t1ww
来源:https://stackoverflow.com/questions/58809648/how-to-validate-multiple-phone-numbers-with-formik-yup