reactjsmaterial-uiformikyupformik-material-ui

Formik field mapping and yup validation not working on sign in form


I am trying to create a simple sign in form using formik and material ui however when I enter data into the form the fields are still coming blank and validation is not working.

import React from 'react';
import { useFormik, Formik, Form } from 'formik';
import * as yup from 'yup';
import Button from '@material-ui/core/Button';
import Field from '@material-ui/core/TextField';

const SignIn = () => {

    const validation = yup.object({
        email: yup
        .string()
        .email('Enter a valid email')
        .required('Email is required'),
        password: yup
        .string()
        .min(8, 'Password should be of minimum 8 characters length')
        .required('Password is required'),
    });

    
    return (
        <div>
            <h2>Sign In</h2>
            <Formik
                initialValues={{ email: "", password: ""}}
                validationSchema={validation}
                onSubmit={(values, { setSubmitting }) => {
                    console.log(JSON.stringify(values, null, 2));
                    setSubmitting(false);
                }}
            >
                <Form>
                    <Field id='email' name='email' label='Email' type='text' variant='outlined'></Field>
                    <Field id='password' label='Password' type='text' variant='outlined'></Field>
                    <Button className='submit' type='submit' variant='outlined'>Login</Button>
                </Form>
            </Formik>
        </div>
    );
}

export default SignIn


Solution

  • As I understand it, to ensure proper integration of Yup validations within Formik, it's crucial to bind the onBlur attribute alongside the field values. This binding enables Formik to track user interaction with the form fields, triggering validation checks as necessary. Without this setup, the validations specified using Yup won't be activated. Essentially, by associating the onBlur event handler with each field, Formik can accurately validate user input upon field interaction, providing a seamless and responsive form validation experience.

    Below are a few code suggestions/changes. Hope this helps:p

    import React from 'react';
    import { useFormik, Formik, Form } from 'formik';
    import * as yup from 'yup';
    import Button from '@material-ui/core/Button';
    import TextField from '@material-ui/core/TextField'; // Changed Field to TextField
    
    const SignIn = () => {
        const validation = yup.object({
            email: yup
            .string()
            .email('Enter a valid email')
            .required('Email is required'),
            password: yup
            .string()
            .min(8, 'Password should be of minimum 8 characters length')
            .required('Password is required'),
        });
    
        const formik = useFormik({
            initialValues: { email: '', password: '' },
            validationSchema: validation,
            onSubmit: (values, { setSubmitting }) => {
                console.log(JSON.stringify(values, null, 2));
                setSubmitting(false);
            },
        });
        
        return (
            <div>
                <h2>Sign In</h2>
                <Form onSubmit={formik.handleSubmit}>
                    <TextField 
                        id='email' 
                        name='email' 
                        label='Email' 
                        type='text' 
                        variant='outlined' 
                        value={formik.values.email} 
                        onBlur={formik.handleBlur} 
                        onChange={formik.handleChange} 
                    />
                    {formik.touched.email && formik.errors.email ? (
                        <div>{formik.errors.email}</div>
                    ) : null}
                    <TextField 
                        id='password' 
                        name='password' 
                        label='Password' 
                        type='password' // Changed to password type for password field
                        variant='outlined' 
                        value={formik.values.password} 
                        onBlur={formik.handleBlur} 
                        onChange={formik.handleChange} 
                    />
                    {formik.touched.password && formik.errors.password ? (
                        <div>{formik.errors.password}</div>
                    ) : null}
                    <Button className='submit' type='submit' variant='outlined'>Login</Button>
                </Form>
            </div>
        );
    }
    
    export default SignIn;