Optimizing Formik in React Native: Best Coding Practices

Optimizing Formik in React Native: Best Coding Practices

ยท

2 min read

Here are some best coding practices to follow when using Formik in React Native:

  1. 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.

  2. Use the useFormik hook to create the formik object, and use the object to interact with the form state and functions.

  3. Use the FormikProvider component to provide the formik object to the child components that need it.

  4. 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.

Did you find this article valuable?

Support TopGun by becoming a sponsor. Any amount is appreciated!

ย