jaredpalmer / formik

Build forms in React, without the tears 😭
https://formik.org
Apache License 2.0
33.87k stars 2.78k forks source link

How disable the auto reset form on submit in formik? #2369

Open veronesecoms opened 4 years ago

veronesecoms commented 4 years ago

❓Question

I have a form that i'm controlling by formik, when i fill all the fields and press the buttom submit, the function onSubmit is called and my form have this values reseted.

Sometimes my data is incorrect (like a duplicate email) and i need to persist this data.

How i can do this?

This is my code:

        const schema = Yup.object().shape({
            login: Yup.string()
                .email('Email não possui formato válido')
                .required('Informe o email!'),
            password: Yup.string().required('Informe a senha!'),
        })

        const formik = useFormik({
            initialValues: {
              login: '', password: '', inactive: false
            },

            validationSchema: schema,
            onSubmit: values => {
                registerUser(values)
            }
        })

    return (
        <form onSubmit={formik.handleSubmit} className={classes.form} noValidate>
            <Grid container spacing={3}>

                <Grid item xs={12}>
                    <Typography className={classes.observation} component="h6">* Necessário preenchimento do cadastro geral para liberar permissão de telas</Typography>
                </Grid>

                <Grid item xs={5}>
                    <TextField
                        value={formik.values.login}
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        helperText={formik.touched.login ? formik.errors.login : ""}
                        error={formik.touched.login && Boolean(formik.errors.login)}
                        variant="outlined"
                        margin="normal"
                        required
                        fullWidth
                        id="email"
                        label="E-mail"
                        name="login"
                        autoComplete="email"
                    />
                </Grid>

                <Grid item xs={5}>
                    <TextField
                        value={formik.values.password}
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        helperText={formik.touched.password ? formik.errors.password : ""}
                        error={formik.touched.password && Boolean(formik.errors.password)}
                        variant="outlined"
                        margin="normal"
                        required
                        fullWidth
                        type="password"
                        id="password"
                        label="Senha"
                        name="password"
                    />
                </Grid>

                <Grid item xs={2}>
                    <FormControlLabel
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        value={formik.values.inactive}
                        control={<Switch color="primary" />}
                        label="Inativo"
                        labelPlacement="top"
                    />
                </Grid>

                <Grid item xs={3}>
                    <Button fullWidth 
                        variant="contained" 
                        color="primary"
                        type="submit"
                    >
                        Cadastrar
                    </Button>
                </Grid>

            </Grid>
        </form>
    );
shubham-solytics commented 3 years ago

Still no answer formik is getting worst day by day

ghost commented 3 years ago

there is no way to solve it yet?

bmccaw commented 3 years ago

Anyone find an answer for this?

johnrom commented 3 years ago

Formik does not automatically reset your values after submit. I can only assume you are getting values from redux or another state manager, and the props returned from that state manager are causing the props passed to your form to trigger reinitialize. To confirm, you can do enableReinitialize={false}. Please provide a codesandbox and someone may be able to help further.

To anyone asking about answers, you can also provide a codesandbox to aid in investigation.

pLavrenov commented 3 years ago

apollo client + formik, resets field values ​​after server response

enableReinitialize=false, not work

johnrom commented 3 years ago

@pLavrenov please consider providing a codesandbox to aid in investigation. As far as I'm aware, the only reason Formik would be reset is if you:

a) manually call resetForm b) lose identity on your Formik form by a parent re-rendering and not forming a stable hierarchy of components (use key={} to prevent identity loss) (<-- this is the one that gets everyone) c) passing enableReinitialize and updating initialX props

Beyond that, we'll need a reproduction in order to help.

talentlessguy commented 3 years ago

still an issue, setting enableReinitialize to false doesn't change it, it still resets :\

and I don't call resetForm manually

if needed, I can spin up a repro

johnrom commented 3 years ago

A repro is basically the only way we can help diagnose an issue of this nature.

mvarsakelis commented 3 years ago

@johnrom I am having this issue also. I'm new to react. What I am attempting to do is show an alert after an API call. If a response has data then I show a success Alert. If something went wrong then I show a danger Alert. I cannot figure out how to keep the form values if no response was sent. Maybe I'm calling the Alert wrong and causing it to reload no matter what.

I have never messed with CodeSandbox but I created one and I hope it's enough to show you how I'm attempting to accomplish this: https://codesandbox.io/s/vigorous-bush-c61mq

I also have asked on stackoverflow: https://stackoverflow.com/questions/69122198/how-to-retain-form-values-after-submission-with-formik

Thanks in advance if you can give me any hints of what I'm doing wrong

... update ... I got it working by changing the conditional showing of the alert to be separate from where the form is displayed. Doing it like I was was re-rendering the form and resetting the values. See stackoverflow above

mumarqayyum051 commented 2 years ago

I'm new to react but not new to Web development. Struggling to find a fix for this tiny issue but couldn't find anything relevant to do the trick

mumarqayyum051 commented 2 years ago

I'm new to react but not new to Web development. Struggling to find a fix for this tiny issue but couldn't find anything relevant to do the trick

cosoc commented 1 year ago

I found the reset data phenomenon, but I shouldn't appear in js

Bug

const onSubmit =(values:any, actions: any) =>{
        //  卧槽!当你在这里修改[values]的值时候,他会把Formik内部的对应数据的也修改了.这不是 java引用 和 c中的&运算符?
       //  Dammit! When you modify the value of [values] here, it will also modify the corresponding data in Formik. Isn't this java reference and the & operator in c?
        values.yourFiledName = "any value"; 
}

Solve(解决方法)

const onSubmit =(values:any, actions: any) =>{
         // 重新复制一个对象
         // copye a objec
         let paylaod = JSON.parse(JSON.stringify(values)); 
        paylaod.yourFiledName =  "any value"; 
}

表单结构

    <Formik
           innerRef={formikRef}
            validate={validate}
            initialValues={{ 
                yourFiledName: '',
            }}
            onSubmit={onSubmit}
        >
        {(props) => (
            <Form style={{width:"100%"}}>
                <Field name='deviceType'>
                    {( data:any ) => (                                
                    <FormControl isRequired>
                        <FormLabel>filed name</FormLabel>
                        <Input {...data.field} size={"sm"} readOnly />
                    </FormControl>
                    )}
                </Field>
                <div className={styles.submit}>
                    <Button
                        mt={4}
                        colorScheme='green'
                        isLoading={props.isSubmitting}
                        type='submit'
                    >
                        提交
                    </Button>
                </div>
            </Form>
        )}
    </Formik>

Repair suggestion(修复建议)

When triggered by an internal event, the internal variable should not be passed out directly, which will cause security problems. The internal details should be shielded and a copy object should be passed out.

Freeze777 commented 1 year ago

Any solution to this problem? I've landed on this problem today. Formik resets the form even after setting enableReinitialize=false

sunpietro commented 1 year ago

I'm also having this issue when the onSubmit callback is async and finally redirecting a user with window.location.href thing.

RAHMANIABOUBEKER commented 1 year ago

@sunpietro The issue is caused by the values object when getting mutated, so to fix this you can do JSON.parse(JSON.stringify(values))

Hope this could help

canerkaynar commented 1 year ago

There is a solution that i did Keep current form values by using ref before calling your mutation.

const persistFormValues = useRef({ email: '', password: '', })

const LoginForm = withFormik<FormProps, FormValues>({ mapPropsToValues: (props) => ({ email: props.email || persistFormValues.current.email, password: props.password || persistFormValues.current.password, }), validationSchema: validations, handleSubmit: async (values, { props, setSubmitting }) => { const { email, password } = values persistFormValues.current = values Keyboard.dismiss() login({ email, password }) setSubmitting(false) }, displayName: 'LoginForm', })(Form)

binarytrance commented 1 year ago

I was facing the same issue. Fortunately, setting enableReinitialize=false worked for me. The values weren't reset after submit.

andrewinsoul commented 12 months ago

The possible guess for this issue is that you are altering a state variable in the function. If Formik is properly used, you can effectively manage the states of your form with Formik without needing React State

R0land013 commented 5 months ago

Hi there. I had the same issue. I found a workaround using useRef to store the initialValues of Formik. Then when user tries to submit I update the value of the ref. Then the next time the form gets rendered it will use the initialValues of the ref that always will keep the values before the form was submitted. Of course I needed enableReinitialize=true on Formik.

const initialValuesRef = useRef({
        task: '',
        date: new Date()
    });

<Formik
    enableReinitialize
    initialValues={initialValuesRef.current}...

// Inside Formik component on onClick submit
// Here I will keep the values before get cleared by fromik
initialValuesRef.current = formikProps.values;
formikProps.handleSubmit();