Here are some best coding practices to follow when using Formik in React Native:
Use props to pass initialValues and onSubmit function to the Formik component, and extract the validate function and other configuration options to the component that renders the form.
Use the useFormik hook to create the formik object, and use the object to interact with the form state and functions.
Use the FormikProvider component to provide the formik object to the child components that need it.
Use the Field component to render form fields, and extract the field-specific logic (e.g. validation) to separate functions.
Here's an updated version of the code that follows these best practices:
import { Field, Formik, FormikProvider, useFormik } from 'formik';
import React from 'react';
import { Button, Text, TextInput, View } from 'react-native';
const validatePhoneNumber = value => {
if (!value) {
return 'Required';
} else if (!/^[0-9]+$/.test(value)) {
return 'Must be only digits';
} else if (value.length !== 10) {
return 'Must be exactly 10 digits';
}
};
const PhoneNumberField = ({ label, ...props }) => {
const [field, meta] = useField(props);
const { value, onBlur } = field;
const { error, touched } = meta;
return (
<View>
<Text>{label}</Text>
<TextInput
onChangeText={value => props.onChange(props.name)(value)}
onBlur={onBlur}
value={value}
style={{ borderColor: "grey", borderWidth: 1 }}
placeholder={'Enter phone number'}
keyboardType={'phone-pad'}
maxLength={10}
/>
{error && touched && <Text style={{ color: 'red' }}>{error}</Text>}
</View>
);
};
const MyForm = ({ initialValues, onSubmit }) => {
const formik = useFormik({
initialValues,
onSubmit,
validate: validatePhoneNumber,
});
return (
<FormikProvider value={formik}>
<View>
<Field
component={PhoneNumberField}
label="Phone number"
name="phoneNumber"
validate={validatePhoneNumber}
/>
{formik.values.phoneNumber.length === 10 &&
<Text style={{ color: 'green' }}>Good to go!</Text>
}
<Button onPress={formik.handleSubmit} color="grey" title="Submit" />
</View>
</FormikProvider>
);
};
// Usage example:
<MyForm
initialValues={{ phoneNumber: '' }}
onSubmit={values => console.log(values)}
/>
In this updated code, we define a validatePhoneNumber
function to validate the phone number field. We also define a PhoneNumberField
component that renders the phone number field using the useField
hook from Formik.
Inside the MyForm
component, we use the useFormik
hook to create the formik
object. We then pass the object to the FormikProvider
component and use the Field
component to render the phone number field.
By using the Field
component, we can extract the field-specific logic to the PhoneNumberField
component, making it easier to read and test. We can also reuse the PhoneNumberField
component in other forms.