question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

form component renders twice + isValid turns true only on blur

See original GitHub issue

Hi everyone,

I have the following component using Formik … i have two problems i am struggling to fix for half a day now 😦

  1. The console.log u see there renders twice per change … so if i input 1 character my component renders twice
  2. The form has only one input with basic validation … for some reason … while i type the email the form does become valid until the input looses focus

Can anyone give me any kind of feedback on what i am doing wrong?

thanks

const RecoverPasswordForm = ({ updateCaptchaHandle, processSubmit, history, values, errors, touched, isSubmitting, isValid, status, resetForm, setErrors }) => {
    console.log('render forgot password form');
    return (<div className="m-login__forget-password animated flipInX">
        <div className="m-login__head" style={{ marginBottom: '30px' }}>
            <h3 className="m-login__title">Forgotten Password ?</h3>
            <div className="m-login__desc">Enter your email to reset your password:</div>
        </div>
        <Form className={ "m-form m-form--fit m-form--label-align-right" + (errors.forgotPassword || (status && status.success) ? " m-t-20" : "") }>
            <ReCaptcha reference={updateCaptchaHandle} onChange={(captcha) => processSubmit(captcha, resetForm, setErrors)} />
            {status && status.success && <div className="m-alert m-alert--outline alert alert-success alert-dismissible" role="alert">
                <span>Please check you inbox! If we find any record of your email we will send there instructions for recover you password!</span>
            </div>}
            {errors.forgotPassword && <div className="m-alert m-alert--outline alert alert-danger alert-dismissible" role="alert">
                <span>We tried but something went wrong</span>
            </div>}
            <div className={"form-group m-form__group p-b-0" + (touched.email && errors.email ? " has-danger": "")}>
                <label htmlFor="email">Your Email</label>
                <Field className="form-control m-input m-input--air" type="text" id="email" name="email" autoComplete="off" placeholder="john.smith@example.com" />
                <div id="email-error" className="form-control-feedback">{ touched.email && errors.email ? errors.email : '\u00A0' }</div>
            </div>
            <div className="row m-form__actions">
                <div className="col m--align-left">
                    {isSubmitting?"true":"false"} / {isValid?"true":"false"}
                    <button disabled={isSubmitting || !isValid} id="m_login_forget_password_submit" className={"btn btn-focus m-btn m-btn--pill m-btn--custom m-btn--air" + (isSubmitting ? " m-loader m-loader--light m-loader--left" : "")}>Request</button>
                </div>
                <div className="col m--align-right">
                    <button onClick={ () => !isSubmitting && history.push("/auth") } type="button" id="m_login_forget_password_cancel" className="btn btn-outline-focus m-btn m-btn--pill m-btn--custom">Cancel</button>
                </div>
            </div>
        </Form>
    </div>);
}


const RecoverPasswordFormHOC = compose(
    withRouter,
    graphql(ForgotPasswordMutation, {
        name: 'forgotPasswordMutation'
    }),
    withState('captchaHandle', 'setCaptchaHandle', null),
    withState('formValues', 'setFormValues', null),
    withHandlers({
        updateCaptchaHandle: ({ setCaptchaHandle }) => (handle) => setCaptchaHandle(handle),
        processSubmit: ({ formValues, forgotPasswordMutation, history }) => async (captcha, resetForm, setErrors) => {
            const { data: { forgotPassword: { status }} } = await forgotPasswordMutation({
                variables: {
                    email: formValues.email
                }
            });
            resetForm();
            if (status) {
                history.push({
                    pathname: '/auth',
                    state: { recoverEmailSent: true }
                });
            } else {
                setErrors({ forgotPassword: true });
            }
        }
    }),
    withFormik({
        mapPropsToValues({ email }) {
            return {
                email: email || ''
            }
        },
        validationSchema: Yup.object().shape({
            email: Yup.string().email(`That's not really an email`).required(`FYI we need your email to sign you in`).max(100, '100 characters we think are enough for your email'),
        }),
        validateOnChange: true,
        handleSubmit: (values, { props: { setFormValues, captchaHandle } }) => {
            setFormValues(values);
            captchaHandle.execute();
        }
    }),
    onlyUpdateForKeys(['isSubmitting', 'isValid', 'errors', 'touched', 'status', 'values']),
    pure
);

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

4reactions
jaredpalmercommented, Feb 3, 2018

When we initially went with Yup, async was the only option. It was pretty annoying tbh to design around. I think it’d be worth moving to sync Yup because I would take a guess that 95% of Yup schema’s only use sync features anyways.

3reactions
jaredpalmercommented, Feb 3, 2018

Edit: it would break lots of forms.

Read more comments on GitHub >

github_iconTop Results From Across the Web

'isValid' is always false - Stack Overflow
The component rendered twice because of React.StrictMode . Strict mode can't automatically detect side effects for you, but it can help you ...
Read more >
React Components rendered twice — any way to fix this?
Let's find out if there is a way to avoid this problem by trying different implementations.
Read more >
react-hook-form controlled input onblur doesn't work - You.com
In your code, the form mode is onBlur . it means the validation is triggered on blur event (unfocus the input). When you...
Read more >
Form Validation in React.js using React Functional ...
In a React component, state is the data context for the views. It is natural to assign the values received from form fields...
Read more >
3 ways to autofocus an input in React that ALMOST always work!
Thus, if we render the input element after the component mounts, we won't focus it. In this example, imagine loading is true for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found