Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formik values not updated properly when browser autofills/autocomplete #3165

Open
pabloimrik17 opened this issue Apr 28, 2021 · 14 comments
Open

Comments

@pabloimrik17
Copy link

Bug report

Current Behavior

Formik do not update properly values property when browser autofills user/password fields.

As you can see on this gif the input has visible values, but not internally (check the console log info on the first two renders)

Once i touch the screen (in this case opening the dev tools with F12) the onChanges are triggered and then formik updates. Also notice how the clear button is visible at end the of each input once i touch the screen.

formik 1

formik 2

image

Im using Ant Desing inputs, but the issue happens too on vanilla HTML inputs

Expected behavior

Formik should have the values updated with the browser autocomplete values

Reproducible example

Im not sure how to make the reproducible example

Your environment

Software Version(s)
Formik 2.2.6
React 16.13.1
TypeScript 4.2.3
Browser Chrome 90.0.4430.93
npm/Yarn 12.18.2
Operating System Windows 10
@pabloimrik17
Copy link
Author

Any update?

@johnrom
Copy link
Collaborator

johnrom commented May 13, 2021

This is an upstream issue and a duplicate. There is an issue on React's repository regarding autofill not updating controlled inputs.

I'm on mobile, but if you search these issues for autofill you should see the source issue which links to the React issue.

@johnrom
Copy link
Collaborator

johnrom commented May 13, 2021

#721

@github-actions
Copy link
Contributor

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 60 days

@github-actions github-actions bot added the stale label Jun 13, 2021
@lironezra
Copy link

Facing same issue.
There is any solution for this problem?
Thanks guys!

@github-actions github-actions bot removed the stale label Jun 28, 2021
@vicary
Copy link

vicary commented Jul 26, 2021

Further reading the upstream issue facebook/react#1159 and https://bugs.chromium.org/p/chromium/issues/detail?id=1166619, it seems that Chrome is giving Javascript access to input values after user interactions.

If Chrome is preventing script spies for security reasons, I don't think they're gonna simulate the onChange event any time soon. This essentially breaks the whole controlled components design in React.

As a workaround, Formik should be possible to perform a last-minute update by reading the submit event before firing onSubmit.

What do you think?

@johnrom
Copy link
Collaborator

johnrom commented Jul 26, 2021

I posted a possible fix here -- if that problem is that autofill is occuring before React initializes. If the problem occurs on future "fill" commands using the autofill after the page has already been loaded, it's probably an unsolvable issue (or at least would require sad workarounds like manually reading uncontrolled inputs in a controlled form library).

#1047 (comment)

Formik is unfortunately a controlled-input library so we wouldn't likely change to use uncontrolled inputs any time soon.

@rfirmansyh
Copy link

rfirmansyh commented Nov 12, 2021

Screen Shot 2021-11-13 at 01 05 27

I just found the solution, maybe isn't best practice, but this save my time since I also got confused why autofill Mozilla didn't work when I try to login on my app

@DaviGadelhaLeitao
Copy link

I'm with that issue and having to workaround this, it's unfortunate.

@mertcanekiz
Copy link

If you don't want to use useFormik and are using <Formik> you can use my slightly modified workaround that uses the same principle as @rfirmansyh 's:

...

<Formik ...>
  {(props) => (
    <AutofillSync props={props} />
    ...
  )}
</Formik>

...


const AutofillSync = ({ props }: { props: FormikProps<FormData> }) => {
  useEffect(() => {
    if (
      (document.querySelector('input[name="email"]') as HTMLInputElement)?.value ||
      (document.querySelector('input[name="password"]') as HTMLInputElement)?.value
    ) {
      if (!props.values.email || !props.values.password) {
        props.setValues({
          email: (document.querySelector('input[name="email"]') as HTMLInputElement)?.value || "",
          password: (document.querySelector('input[name="password"]') as HTMLInputElement)?.value || "",
        });
      }
    }
  });
  return null;
}

@JonathanCallewaert
Copy link

JonathanCallewaert commented Sep 21, 2022

@mertcanekiz I agree, but I had to add empty dependency to the useEffect:

 useEffect(() => {
    if (
      (document.querySelector('input[name="email"]') as HTMLInputElement)?.value ||
      (document.querySelector('input[name="password"]') as HTMLInputElement)?.value
    ) {
      if (!props.values.email || !props.values.password) {
        props.setValues({
          email: (document.querySelector('input[name="email"]') as HTMLInputElement)?.value || '',
          password: (document.querySelector('input[name="password"]') as HTMLInputElement)?.value || '',
        });
      }
    }
  }, []);

Else, I got in an infinite loop

@exsesx
Copy link

exsesx commented Oct 26, 2022

Any updates on this one?

Many users use password managers these days, and having this issue opened forces developers to find alternatives, react-hook-form or something.

@Anastasia-kot
Copy link

try: https://www.npmjs.com/package/detect-autofill

add eventListener to Field component and set flag "isAutocompleted" to form state

@tripolskypetr
Copy link

Looks like all these methods with autofill prop are simple ignored by Google Chrome since 2022. I suggest a different method: using readOnly={true} until focus event

Keep in mind that on mobile safari keyboard will not shown if input field change readonly state after focus event, so you need to process onTouchStart too. Heres the link to the source code of usePreventAutofill hook

import { usePreventAutofill } from 'react-declarative';

...

const preventAutofill = usePreventAutofill();

...

return (
  <InputBase

      ...

      {...preventAutofill}
  />   
);
 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests