I am trying to develop a form using Formik, Material UI, and React-phone-number-input lib (for phone number formatting). I faced a problem. When a phone number is being entered, one is already formatted as intended, but that number is not inserted into Formik state. So, the phone number value is not visible for Formik, and as a result, Formik can not take away an error marker "Required", when some value is entered. Having Guessed, I use react-phone-number-input lib and Formik in the not right way together. How to use them right?
github:
I have the base file src/App.js. Where I use PhoneNumberInput ponent. This is actually my phone number input.
export const App = () => {
return (
<>
<Formik
initialValues={{
firstName: '',
lastName: '',
email: '',
phoneNumber: '',
}}
validationSchema={Yup.object({
firstName: Yup.string()
.max(15, 'Have to be 15 characters or less')
.required('Required'),
lastName: Yup.string()
.max(20, 'Have to be 20 or less characters')
.required('Required'),
email: Yup.string().required('Required.'),
phoneNumber: Yup.string().required('Required'),
})}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2))
setSubmitting(false)
}, 400)
}}
>
{context => (
<Form>
<MainContainer>
<Title text={'Step 2'} iconRender={<AccountCircleRoundedIcon />} />
<TextInput text={'Email'} name={'email'} />
<PhoneNumberInput
name={'phoneNumber'}
label={'Phone Number'}
context={context}
/>
<MyButton>Next</MyButton>
</MainContainer>
</Form>
)}
</Formik>
</>
)
}
And in src/ponents/PhoneNumberInput/PhoneNumberInput.js I define PhoneNumberInput ponent. I use Input ponent from react-phone-number-input to have the opportunity to use a custom input.
const MyField = React.forwardRef(function custom(props, ref) {
const { name, label } = props
return (
<Field
{...props}
ponent={TextField}
label={label}
name={name}
variant="outlined"
inputRef={ref}
fullWidth
/>
)
})
export const PhoneNumberInput = ({ text, ...props }) => {
const [value, setValue] = useState()
const [focus, setFocus] = useState(false)
console.log(props.context)
return (
<>
<Input
{...props}
country="UA"
international={focus}
value={value}
withCountryCallingCode
onChange={setValue}
inputComponent={MyField}
onFocus={() => setFocus(true)}
control={props.control}
/>
</>
)
}
What is wrong? How to tackle that?
I am trying to develop a form using Formik, Material UI, and React-phone-number-input lib (for phone number formatting). I faced a problem. When a phone number is being entered, one is already formatted as intended, but that number is not inserted into Formik state. So, the phone number value is not visible for Formik, and as a result, Formik can not take away an error marker "Required", when some value is entered. Having Guessed, I use react-phone-number-input lib and Formik in the not right way together. How to use them right?
github:https://github./AlexKor-5/FormChallenge/tree/0d37064ef54c8e87a6effb950575a5a3817d9220
I have the base file src/App.js. Where I use PhoneNumberInput ponent. This is actually my phone number input.
export const App = () => {
return (
<>
<Formik
initialValues={{
firstName: '',
lastName: '',
email: '',
phoneNumber: '',
}}
validationSchema={Yup.object({
firstName: Yup.string()
.max(15, 'Have to be 15 characters or less')
.required('Required'),
lastName: Yup.string()
.max(20, 'Have to be 20 or less characters')
.required('Required'),
email: Yup.string().required('Required.'),
phoneNumber: Yup.string().required('Required'),
})}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2))
setSubmitting(false)
}, 400)
}}
>
{context => (
<Form>
<MainContainer>
<Title text={'Step 2'} iconRender={<AccountCircleRoundedIcon />} />
<TextInput text={'Email'} name={'email'} />
<PhoneNumberInput
name={'phoneNumber'}
label={'Phone Number'}
context={context}
/>
<MyButton>Next</MyButton>
</MainContainer>
</Form>
)}
</Formik>
</>
)
}
And in src/ponents/PhoneNumberInput/PhoneNumberInput.js I define PhoneNumberInput ponent. I use Input ponent from react-phone-number-input to have the opportunity to use a custom input.
const MyField = React.forwardRef(function custom(props, ref) {
const { name, label } = props
return (
<Field
{...props}
ponent={TextField}
label={label}
name={name}
variant="outlined"
inputRef={ref}
fullWidth
/>
)
})
export const PhoneNumberInput = ({ text, ...props }) => {
const [value, setValue] = useState()
const [focus, setFocus] = useState(false)
console.log(props.context)
return (
<>
<Input
{...props}
country="UA"
international={focus}
value={value}
withCountryCallingCode
onChange={setValue}
inputComponent={MyField}
onFocus={() => setFocus(true)}
control={props.control}
/>
</>
)
}
What is wrong? How to tackle that?
Share Improve this question asked May 3, 2022 at 16:33 AlexKor5AlexKor5 311 silver badge4 bronze badges1 Answer
Reset to default 5Actually it's pretty easy to implement with the help of Formik hooks
This is my working solution:
import PhoneInput from "react-phone-number-input";
import { useField } from "formik";
import FieldWrapper from "../FieldWrapper";
const PhoneInputField = ({ label, ...props }) => {
const [field, meta, helpers] = useField(props.name);
return (
<FieldWrapper label={label} meta={meta} {...props}>
<PhoneInput
{...props}
{...field}
value={field.value}
defaultCountry="NO"
onChange={(value) => {
helpers.setValue(value);
}}
/>
</FieldWrapper>
);
};
export default PhoneInputField;
Then use this ponent in your Formik Form as so
// your boilerplate code ect...
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
>
{({ handleSubmit, isSubmitting }) => (
<FieldPhoneInput
label="Phone Number"
name="phone"
type="tel"
placeholder="Write your phone number here"
/>
)}
</Formik>