-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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
Provide a way to handle browser-autocompleted form values on controlled components #1159
Comments
This seems to discuss it a bit more: http://stackoverflow.com/a/11710295 |
atm i am using this https://github.com/tbosch/autofill-event |
cc me |
(@visionscaper tip: press "Subscribe" on the right column.) |
Any updates or suggested best practices on this one? The autofill event polyfill seems like a sledgehammer solution. |
Safari (8) does dispatch change events on autofill, but they don't bubble so they don't reach the react handler. |
A related discussion on angular/angular.js#1460 was closed, with some suggestions, one of them being making use of https://github.com/tbosch/autofill-event to fire change event on autofill, manually. I think, we can close here as well. |
It would be nice to have the autofill-event as part of React, possible as an addon. This functionality is going to be necessary for virtually everyone using React for form validation. The autofill-event script also adds a dependency for jQuery, which may be undesirable in many cases. |
This is a browser bug that effects all browsers a little differently. I think just because angular punted on trying to work around or fix it doesn't mean react should. It's a common thing but I understand if this is a "wontfix". I'm not super well versed on the various browser's bug trackers, but it would be nice if someone who is could find or open issues for this. I think the react team has more weight then most users would when opening an issue about it. And we could tract the tickets here for the react developers who are interested. |
I caught up with the angular thread. Firefox has issues with password fields (https://bugzilla.mozilla.org/show_bug.cgi?id=950510 is still open), no word on safari's bug #, chrome is fixed. |
Issues are already being tracked at some places - angular/angular.js#1460 (comment) |
The Chrome issue is now closed, but it pretty clearly does not work in Chrome 50 with React 0.14.8. |
no fix yet? |
I feel like this was working for a while and broke again recently? |
any update on this issue? |
@dwoodwardgb |
Add <form> element, as some browsers won't autofill fields not contained in form. Remove username and password bindings, and explicitly read inputs instead. Some browsers do not fire onChange events when a field is autofilled for security reasons, so Vue bindings don't register the change. facebook/react#1159 (comment)
Add <form> element, as some browsers won't autofill fields not contained in form. Remove username and password bindings, and explicitly read inputs instead. Some browsers do not fire onChange events when a field is autofilled for security reasons, so Vue bindings don't register the change. facebook/react#1159 (comment)
You could set autocomplete="off" attribute(HTML5), or record input value in url hash. |
Dug into this issue a bit more: Chromium made a change to emit both "change" and "input" native events based on this bug report: https://bugs.chromium.org/p/chromium/issues/detail?id=813175. However, for some reason React still does not trigger the Can someone from the React team take a deeper look into the React In the meantime, I'm using the |
I think this is the commit in Chrome that broke the behavior: It removes the |
@nfiacco that commit is from 2018, this issue was opened in 2014, so on the surface that doesn't add up... Unless the cause now is different to when the issue was originally opened? |
I came back from 2022 |
This is old Chrome bug, I just open https://bugs.chromium.org/p/chromium/issues/detail?id=1166619 for it. |
I did a workaround this way in my app:
|
@loburets Thank you so much! your solution has saved me. |
Opened a bug at Chromium because it is related to Chromium or its Blink Engine. https://bugs.chromium.org/p/chromium/issues/detail?id=1405170 |
Note that @loburets solution triggers a React warning when using Server-Side-Rendering. Have to switch to |
a note for anyone who is having the same issue as me, I had the onchange event modify a value in an object, this did not work, for some reason when I made the value I wanted to change it's own state it worked, maybe this had to do with trying to change multiple values in an object at the same time when doing multiple autofill, not good enough yet to know for sure |
We use react-hook-form (in Next.js) and leverage the onChange event on a controlled input component to focus -> blur the input, which triggers validation: import React, { useEffect, useState, useRef } from "react"
export default function Text({
id,
useForm=undefined,
validation={},
className="",
placeholder="",
type="text",
value="",
onChange=undefined,
...props
}) {
const { register, control, setValue, trigger, getValues, watch } = useForm;
// Inherit validated error state
const errors = useForm.formState.errors;
// Value state
const [valueState, setValueState] = useState(value ?? "")
// Input change handler
const onChangeHandler = (e) => {
// Fix for autofill
e.target.focus()
e.target.blur()
setValueState(e.target.value)
onChange && onChange(e.target.value)
}
// Parent change handler
useEffect(() => {
setValueState(value)
}, [value])
return (
<div className={"flex flex-col " + className}>
<input
{...register && register(id, { ...validation })}
className={"p-2.5"}
placeholder={placeholder}
type={type}
value={valueState}
onChange={onChangeHandler}
/>
{errors[id] && (<p className="text-sm text-red py-2">{errors[id].message}</p>)}
</div>
);
} NOTE: For the example above the useForm hook is deconstructed in each child component, but fired in the parent, eg: export default function Page() {
const form = useForm()
const onSubmit = (data, e) => {
console.log(data, e)
}
return <form onSubmit={form.handleSubmit(onSubmit)}>
<Text
id="email"
useForm={form}
placeholder="Email"
validation={{required: 'Email is required'}}
/>
<input type="submit" />
<form>
} |
When there's a controlled component for form names that the user has saved in their browser (common with username/password fields), the browser will sometimes render the page with values in those fields without firing onChange events. If the user submits the form, the component state does not reflect what is showing to the user.
In experimenting with this, it appears that the data is there on load (tested by logging this.refs.myinput.getDOMNode().value)
The text was updated successfully, but these errors were encountered: