A
A
Alex Ozerov2021-06-19 17:53:17
React
Alex Ozerov, 2021-06-19 17:53:17

How to update state inside Formik in React?

Trying to show error message in material ui snackbar.

{errors.email ? handleClickSnackbar(errors.email) : null}

I get:

Cannot update a component (`Login`) while rendering a different component (`Formik`).

How to update state from formica or how to pass error message to snackbar?
Component.jsx

const Login = () => {
    const classes = useStyles();
    const classesReg = useStylesReg();
    const snack_classes = useStylesSnack();
    const [open, setOpen] = useState(false);
    const [checked, setChecked] = useState(false);
    const [ type, setType  ] = useState('password');
    const [ emailMessage, setEmailMessage  ] = useState('');
    const isAuth = useSelector(state => state.user.auth)
    const isLoader = useSelector(state => state.user.loader)
    const message = useSelector(state => state.user.message)
    const loader = localStorage.getItem('userAuth') || isLoader;
    const dispatch = useDispatch();
    const handleClickSnackbar = (message) => {
        setEmailMessage(message)
        setOpen(true);
    };
    const handleCloseSnackbar = (event, reason) => {
        if (reason === 'clickaway') {
            return;
        }
        setOpen(false);
    };
    const validationSchema = yup.object().shape({
        email: yup.string().email().typeError(ERRORS.EMAIL_INVALID).required(),
        password: yup.string().required(ERRORS.PASSWORD_INVALID),
    })
    return isAuth ? (
        <Redirect to='/user' />
    ) : (
        loader ? (
                <Loader text='Loading...' />
            ) : (
                <Fragment>
                    <div className={snack_classes.root}>
                        <Snackbar anchorOrigin={{horizontal: 'right', vertical: 'top'}} open={open} autoHideDuration={10000} onClose={handleCloseSnackbar}>
                            <Alert onClose={handleCloseSnackbar} severity="error">
                                {emailMessage}
                            </Alert>
                        </Snackbar>
                    </div>
                    <div className={classes.root} >
                        <Box display={'flex'} className={classes.paper}>
                            <Box className={clsx(classes.element, classes.right__section)}>
                                <div className={classes.form}>
                                    <div className={classes.form__header}>
                                        <h2>Sign in</h2>
                                    </div>
                                    <Formik
                                        onSubmit={values => {
                                            dispatch(login(values.email, values.password))
                                        }}
                                        initialValues={{
                                            email: '',
                                            password: ''
                                        }}
                                        validationSchema={validationSchema}
                                    >{({values, errors, touched, handleChange, handleBlur, isValid, handleSubmit, dirty}) =>(
                                        <form className={classes.form_control}>
                                            <div className={classes.form__section}>
                                                <div className='form__section-item form__section-label'>
                                                    <label htmlFor="emailAdress">Email adress</label>
                                                </div>
                                                <div className='form__section-item '>
                                                    <Textfield
                                                        placeholder='Enter your email'
                                                        value={values.email}
                                                        onChange={handleChange}
                                                        type='email'
                                                        id='emailAdress'
                                                        className={classes.textfield}
                                                        autoComplete={'on'}
                                                        tabIndex='1'
                                                        name='email'
                                                    />
                                                    {errors.email ? handleClickSnackbar(errors.email) : null}
                                                </div>
                                            </div>
                                            <div className={classes.form__section}>
                                                <div className='form__section-item form__section-label'>
                                                    <label htmlFor="password">Password</label>
                                                </div>
                                                <div className='form__section-item '>
                                                    <Textfield
                                                        placeholder='Enter password'
                                                        value={values.password}
                                                        onChange={handleChange}
                                                        type={type}
                                                        id='password'
                                                        className={classes.textfield}
                                                        tabIndex='2'
                                                        name='password'
                                                    />
                                                </div>
                                            </div>
                                            <div className={clsx(classes.form__section, classes.form__section_showPassword)}>
                                                <Checkbox
                                                    checked={checked}
                                                    onChange={handleChangeFlag}
                                                    id='checkbox'
                                                />
                                                <label htmlFor='checkbox' className='form__section-label__text'>Show password</label>
                                            </div>
                                            <div className={clsx(classes.form__section, classes.form__sectionMargin)}>
                                                <Button disabled={!isValid && !dirty} type='submit' onClick={handleSubmit} variant="contained" className='form__section-signin'>
                                                    <span>Sign in</span>
                                                    <ArrowForwardIcon className={classes.arrow} />
                                                </Button>
                                            </div>
                                            <div className={clsx(classes.form__section, classes.form__section_parent)}>
                                                <span className={classes.form__section_divider} />
                                                <span>or</span>
                                                <span className={classes.form__section_divider} />
                                            </div>
                                            <div className={clsx(classes.form__section, classes.form__btn)}>
                                                <GoogleButton onClick={handleSignIn} variant="outlined" />
                                            </div>
                                            <div className={clsx(classes.form__section, classes.form__section_parent, classes.nodisplay)}>
                                                <span className={clsx(classes.form__section_divider, classes.dividerMargin)} />
                                                <span>or</span>
                                                <span className={classes.form__section_divider} />
                                            </div>
                                            <div className={clsx(classes.form__section, classes.form__signup)}>
                                                <a href="/signup">
                                                    <Button variant="contained" >
                                                        <span>Sign up</span>
                                                    </Button>
                                                </a>
                                            </div>
                                        </form>
                                    ) }
                                    </Formik>
                                </div>
                            </Box>
                        </Box>
                    </div>
                </Fragment>
            )
    )
}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question