formik
formik copied to clipboard
Formik values not updated properly when browser autofills/autocomplete
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.
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 |
Any update?
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.
https://github.com/formium/formik/issues/721
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
Facing same issue. There is any solution for this problem? Thanks guys!
Further reading the upstream issue https://github.com/facebook/react/issues/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?
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).
https://github.com/formium/formik/issues/1047#issuecomment-875708286
Formik is unfortunately a controlled-input library so we wouldn't likely change to use uncontrolled inputs any time soon.

I'm with that issue and having to workaround this, it's unfortunate.
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;
}
@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
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.
try: https://www.npmjs.com/package/detect-autofill
add eventListener to Field component and set flag "isAutocompleted" to form state
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 ofusePreventAutofill
hook
import { usePreventAutofill } from 'react-declarative';
...
const preventAutofill = usePreventAutofill();
...
return (
<InputBase
...
{...preventAutofill}
/>
);