How to setup Formik in Reactjs

How to setup Formik for React forms


Formik is one of most popular React libraries, for managing forms and validations. It has inbuilt state-management system. The Fomik series of posts will cover all essential topics regarding form management using Formik.

Setup

As the very step we need to install the package and prepare our form. In this example we are using a simple login form.

yarn add formik
<form    >		
<input  type="email" placeholder="Email" name="email"  />
<input   type="password" placeholder="Password" name="password" />		 
<button   type='submit'>Sign In</button>
</form>

Formik hook

There are two ways to integrate formik with form, useFormik hook or use Formik component. We go with hook.

let’s configure the hook.

import { useFormik, Formik } from 'formik'
import * as Yup from 'yup'

const validationSchema = Yup.object({
		email: Yup.string().email('Invalid email format').required('Required'),
		password: Yup.string().required('Required'),
	});	
const formikLogin = useFormik({
		initialValues: {
			email: '',
			password: '',
		},
		onSubmit: async values => {
			  console.log(values);		 
		},
		validationSchema 
	});

For the form formik will handle a couple of things, onSubmit, onChange, validation, error generation etc.

All we have to fill few formik values and functions call.

<form   onSubmit={formikLogin.handleSubmit} >		
<input  type="email" placeholder="Email" name="email" value={formikLogin.values.email} onChange={formikLogin.handleChange}  />
{formikLogin.errors.email ? <div>{formikLogin.errors.email}</div> : null}
<input   type="password" placeholder="Password" name="password" value={formikLogin.values.password} onChange={formikLogin.handleChange}   />
{formikLogin.errors.password ? <div>{formik.errors.password}</div> : null}					 
<button   type='submit'>Sign In</button>
</form>

Note that form field’s name and formik field should be same.

Resetting Formik form in Reactjs

How to reset formic forms in Reactjs


Formik is one of most popular React libraries, for managing forms and validations. It has inbuilt state-management system. The Fomik series of posts will cover all essential topics regarding form management using Formik.

Reset

Using the resetForm method we can reset the Formik form fields to initial values.

formikForm.resetForm();

For resetting the form fields with custom values we can use the object syntax, in this, have to use all the fields in the formic object (initalValues) as follows.

	formikForm.resetForm({values: { name: '', email: '',password:'' }});

Yup validation schema in Formik

Use Yup form validation schema in Formik


Formik is one of most popular React libraries, for managing forms and validations. It has inbuilt state-management system. The Fomik series of posts will cover all essential topics regarding form management using Formik.

Yup

Using Yup , the validation rules for formik become simpler. I recommend using this library instead of creating new rules.

First up all , install and import the library to your project.

yarn add yup

Create Yup Object

Let’s create simple Yup schema for Formik, based on this schema Formik hook can generate errors for each form fields.

	 import * as Yup from 'yup'
....
	const loginValidationSchema = Yup.object({
		email: Yup.string().email('Invalid email format').required('Required'),
		password: Yup.string().required('Required'),
	});

In the hook we can specify the schema as follows

	 	const formikLogin = useFormik({
		initialValues: {
			email: '',
			password: '',
		},
		onSubmit: async values => {
		  console.log(values);		 
		},
		validationSchema 
	});

React Prismic CMS slice

React Prismic slice snippets


This is the React Prismic CMS slice code snippet

class Slices extends React.Component {
  render() {
  
    if (this.props.slices) {
      const pageContent = this.props.slices.map((slice, index) => {
          
          if (slice.slice_type === "heading_slice") {
            console.log('heading');
            return (

              <div className="font-bold text-2xl ">
                  {RichText.render(slice.primary.header_rich_text_field)}
              </div>
            );
           }  else if (slice.slice_type === "paragraph_slice") {
              return (
               <div className="text-justify text-2xl">
                 {RichText.render(slice.primary.paragraph_rich_text_field,linkResolver)}
               </div>
            );
           } else if (slice.slice_type === "code_slice"){
            return (
               <div className="relative">
                 <Snippet code={RichText.asText(slice.primary.cod_text_field)} />
               </div>
             );
             }
       
      });
  return  pageContent
    }
    
  }
}

On GitHub , All Gits

React Custom Hook for data validation

React form validation (custom hook) snippets


This is the React Custom Hook for data validation code snippet

//implementuseForm.js
export default function SignUp() {
  
  const { errors, values, handleChange, handleSubmit } = useForm(() => {
         console.log('No errors found')
        console.log('Can implement mutation here')
         
    }, Validate)
  return (
  <form ...>)
  }
//useForm.js
import { EventRounded } from '@mui/icons-material';
import { useState, useEffect } from 'react';

const useForm = (callback, validate) => {

  const [values, setValues] = useState({});
  const [errors, setErrors] = useState({});
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    if (Object.keys(errors).length === 0 && isSubmitting) {
      callback();
    }
  }, [errors]);

  const handleSubmit = (event) => {
    if (event) event.preventDefault();
    setErrors(validate(values));
    setIsSubmitting(true);
    event.target.reset();
  };

  const handleChange = (event) => {
    // event.persist();
    setValues(values => ({ ...values,     [event.target.name]: event.target.value, [event.target.email]: event.target.value }));
  };

  return {
    handleChange,
    handleSubmit,
    values,
    errors,
  }
};

export default useForm;
//validation.js
export default function Validate(values) {
    let errors = {};
    if (!values.email) {
      errors.email = 'Email address is required';
    } else if (!/\S+@\S+\.\S+/.test(values.email)) {
      errors.email = 'Email address is invalid';
    }
    if (!values.name) {
        errors.name = 'Name is required';
      } else if (values.name.length < 3) {
        errors.name = 'Name must be 3 or more characters';
      }
    if (!values.password) {
      errors.password = 'Password is required';
    } else if (values.password.length < 8) {
      errors.password = 'Password must be 8 or more characters';
    }
    return errors;
  };

On GitHub , All Gits

React local storage hook

React local storage example


This is the React local storage hook code snippet

import React from "react";
 
const useLocalStorage=(key, initialValue,clearCache=false)=> {
    // State to store our value
    // Pass initial state function to useState so logic is only executed once
    if(clearCache){window.localStorage.removeItem(key)}
    const [storedValue, setStoredValue] = React.useState(() => {
      try {
        // Get from local storage by key       
        const item = window.localStorage.getItem(key);
        // Parse stored json or if none return initialValue
        return item ? JSON.parse(item) : initialValue;
      } catch (error) {
        // If error also return initialValue
        console.log(error);
        return initialValue;
      }
    });
    // Return a wrapped version of useState's setter function that ...
    // ... persists the new value to localStorage.
    const setValue = (value) => {
      try {
        // Allow value to be a function so we have same API as useState
        const valueToStore =
          value instanceof Function ? value(storedValue) : value;
        // Save state
        setStoredValue(valueToStore);
       
        // Save to local storage
        window.localStorage.setItem(key, JSON.stringify(valueToStore));
      } catch (error) {
        // A more advanced implementation would handle the error case
        console.log(error);
      }
    };
    return [storedValue, setValue];
  }
 
export {
  useLocalStorage,
  
}

Other snippets

Too many re-render in error in React hook

How to solve the Error Too many re-renders. React limits the number of renders in hook


Error Too many re-renders. React limits the number of renders

React raise this error when hook setter function is invoked inside a functional component. The setter should call inside a event handler and the error will go away.

Error code

   const [name, setName] = useLocalStorage("name1", "Bob");
    setName('x')
  return (
    <div>
     {name}
     
    </div>
  );
}

Solution

   const [name, setName] = useLocalStorage("name1", "Bob");
 
  return (
    <div>
     {name}
     <button onClick={()=>setName('meo')}>Meo</button>
    </div>
  );
}

How to enable validation on visited fields in Formik

How to enable validation in visited fields in Formik


We can make form validation of our own with custom hook, but there is a good library for that already, Formik.

Formik provide useForm hook for implementing the validation into our regular form.

Visited field

In input fields in a form get validated using onChange handler provided by the hook, for visited fields Fomik provides onBlur handler.

   const formik = useFormik({
    initialValues: {
      email: '',
      name: '',
      password: 'foobar',
      cid: '',
      lid: ''
    },
    validate,
  onSubmit: (values) => {

In the form field we can use handler as

 <TextField
                    
                    onBlur={formik.handleBlur}
                    
                    error={formik.touched.name && Boolean(formik.errors.name)}
                    helperText={formik.touched.name && formik.errors.name}
                    autoFocus
                  />

Integrating Formik with Form and Mui so easy, isn’t it? Follow posts may help you learn more on the go.

React Hook Form that can simplify form validation

How to setup form validation using React-Hook-Form


In search of a perfect and simple form validation library I found two. It is so easy to get thing done with Formik, but there is also a plan B which simpler than I think.

React Hook Form

This is another form validation library for React developers to make interative forms with ease. The getStarted guide so simple to follow.

Dependency

npm install react-hook-form

We can destructure register, handleSubmit from the useForm hook.

const { register, handleSubmit } = useForm();

Register

The register can be used to register the input. Validation can be passed as the second parameter the register function.

 <input {...register("exampleRequired", { required: true })} />

It can be a complex validation as follows

<input {...register("firstName", { required: true, maxLength: 20 })} />
      <input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} />
      <input type="number" {...register("age", { min: 18, max: 99 })} />

handleSubmit

This can be used to implement our submit logic function

The complete sample

import React from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit } = useForm();
  const onSubmit = data => console.log(data);
   
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName", { required: true, maxLength: 20 })} />
      <input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} />
      <input type="number" {...register("age", { min: 18, max: 99 })} />
      <input type="submit" />
    </form>
  );
}

So I can focus on another component , no worries about Forms and validation

Integrate Formik validation with Mui Form in React

How integrate Mui with React


We can make form validation of our own with custom hook, but there is a good library for that already, Formik.

Formik provide useForm hook for implementing the validation into our regular form. The first step of using Formik is installing the dependency, lol, also we need a validator function to perform validation.

const validate = values => {
  const errors = {};

  if (!values.password) {
    errors.password = 'Required';
  } else if (values.password.length < 6) {
    errors.password = 'Must be must be 6 or more characters';
  }
  if (!values.name) {
    errors.name = 'Name Required';
  } else if (values.name.length < 1) {
    errors.name = 'Minimum of 2 characters';
  }
}

It is just another JavaScript function, which check the parameter value and return some object.

useFormik

Let’s create Formik object,

const formik = useFormik({
    initialValues: {
      email: 'martin@gmail.com',
      name: 'Martin Thomas',   
    },
    validate,
    onSubmit: (values) => {
       alert(JSON.stringify(values, null, 2));
    },
  });

The useForm hook provide handleSubmit, handleChange, handleBlur, isSubmiting event handlers and properties’ , where handleBlur watching the revisited input change and the isSubmiting return true if there is no error.

Initial values

Create initial values for the form input, it can be expressed as simple object

Validate

Validation can be schema , or a function, we can also use external libraries such as yum for schema generation. For our case it is a function

const validate = values => {
  const errors = {};

  if (!values.password) {
    errors.password = 'Required';
  } else if (values.password.length < 6) {
    errors.password = 'Must be must be 6 or more characters';
  }
  if (!values.name) {
    errors.name = 'Name Required';
  } else if (values.name.length < 1) {
    errors.name = 'Minimum of 2 characters';
  }
  if (!values.email) {
    errors.email = 'Required';
  } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
    errors.email = 'Invalid email address';
  }
  if (!values.lid) {
    errors.lid = 'Required';
  }

  if (!values.cid) {
    errors.cid = 'Required';
  }

  return errors;
};

onSubmit

We can wrap submission logic in this handler.

Add validation to the form

In the form section we can us the handlers as formik.handlerName also the value can can be accessed from the value Object. The error object can be use to display the error messages.

import React from 'react';
import { useFormik } from 'formik';
import Button from "@mui/material/Button"; 
import CssBaseline from "@mui/material/CssBaseline";
import TextField from "@mui/material/TextField"; 
import Grid from "@mui/material/Grid";
import Box from "@mui/material/Box"; 
import Typography from "@mui/material/Typography";
import Container from "@mui/material/Container";
import { createTheme, ThemeProvider } from "@mui/material/styles";

 
.... 
const formik = useFormik({
    initialValues: {
      email: 'martin@gmail.com',
      name: 'Martin Thomas',   
    },
    validate,
    onSubmit: (values) => {
       alert(JSON.stringify(values, null, 2));
    },
  });
<div>
      <ThemeProvider theme={theme}>
        <Container component="main" maxWidth="xs">
          <CssBaseline />
          <Box
            sx={{
              marginTop: 8,
              display: "flex",
              flexDirection: "column",
              alignItems: "center",
            }}
          >
            
            <Box
              component="form"
              onSubmit={formik.handleSubmit}
              sx={{ mt: 3 }}
            >

              <Grid container spacing={2}>
                <Grid item xs={12} sm={12}>
                  <TextField
                    autoComplete="given-name"
                    name="name"
                    required
                    fullWidth
                    id="name"
                    label="Name"
                    onBlur={formik.handleBlur}
                    value={formik.values.name}
                    onChange={formik.handleChange}
                    error={formik.touched.name && Boolean(formik.errors.name)}
                    helperText={formik.touched.name && formik.errors.name}
                    autoFocus
                  />
                </Grid>

                <Grid item xs={12}>
                  <TextField
                    required
                    fullWidth
                    id="email"
                    onBlur={formik.handleBlur}
                    label="Email Address"
                    name="email"
                    autoComplete="email"
                    value={formik.values.email}
                    onChange={formik.handleChange}
                    error={formik.touched.email && Boolean(formik.errors.email)}
                    helperText={formik.touched.email && formik.errors.email}
                  />
                </Grid>
                  
              
              <Button
                type="submit"
                 disabled={formik.isSubmitting}
                fullWidth
                variant="contained"
                sx={{ mt: 3, mb: 2 }}
              >
                Sign Up
              </Button>
              

            </Box>
          </Box>      
        </Container>
      </ThemeProvider>       
    </div>

Integrating Formik with Form and Mui so easy.