-
Notifications
You must be signed in to change notification settings - Fork 46.5k
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
Document how React's onChange relates to onInput #3964
Comments
Opened a PR to address this: #4003 |
[#3964] Add note about React's onChange vs. DOM's oninput
[#3964] Add note about React's onChange vs. DOM's oninput
Merged, hurray, we can close this now! 🎉 |
The React onChange event "supersedes" the native DOM "onInput" event. See facebook/react#3964.
wait but why? |
Yeah...why? I don't understand why React chose to make For validation, sometimes we don't want to show validation errors until they're done typing. Or maybe we just don't want a re-render on every keystroke. Now the only way to do that is with onBlur but now we also need to check that the value has changed manually. It's not that big of a deal, but it seems to me like React threw away a useful event and deviated from standard behaviour when there was already an event that does this. |
Agree with mnpenner. With Finally, we have two events - |
Besides there is no easy workaround to replicate such behaviour for the Native events behave such way that moving the slider around triggers an |
Another note: Autofill events (at least on Chrome/OSX) trigger [1]
|
Fixes facebook/react#3964 again after the information was lost in 809e282.
@mnpenner, @evpozdniakov for validation messages or things that you want to wait until they stop typing for use debounce in your event handler instead of waiting until onBlur. |
Still no way of using onChange? I've been writing lots of logic to get around not having a real change event. I think to be a better abstraction, React needs to stick to onChange and let us use onInput without a silly warning. Validation has never been this hard. |
For better or worse, this has been the behavior for quite a while, and many React users rely on it. IMHO, it's probably too late in the game to totally change what "onChange" means in React. But if you feel strongly, maybe do a quick PR to propose a solution with a sensible upgrade path? (Before spending a lot of time on it, get the thoughts of the core team.) |
Definitely a huge design issue with React. Hope it doesn't stay this way forever |
This is a mistake or a feature :/ |
Features are supposed to be useful... this is the opposite of useful. |
For anyone who needs a workaround to get true onChange behavior, you can implement your own component to use HTML's built-in import { Component, InputHTMLAttributes } from 'react';
export interface OnChangeInputProps {
onChange?: (target: HTMLInputElement) => void;
}
/**
* This component restores the 'onChange' behavior of JavaScript.
*
* See:
* - https://reactjs.org/docs/dom-elements.html#onchange
* - https://github.com/facebook/react/issues/3964
* - https://github.com/facebook/react/issues/9657
* - https://github.com/facebook/react/issues/14857
*/
export class OnChangeInput extends Component<Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'onInput' | 'ref'> & OnChangeInputProps> {
private readonly registerCallbacks = (element: HTMLInputElement | null) => {
if (element) {
const onChange: (event: Event) => void = (event) => {
const target = (event.currentTarget!) as HTMLInputElement;
this.props.onChange!(target);
};
element.onchange = this.props.onChange ? onChange : null;
}
};
public render() {
return <input type="text" ref={this.registerCallbacks} {...this.props} onChange={undefined} onInput={undefined} />;
}
} |
Looks like there is an official answer now: |
@dijonkitchen I don't think that's new. See #3964 (comment) |
onChange Note that onChange() was causing errors where the text field and text area inputs were failing to trigger on first deletion after refresh. Switching to onInput() fixed the issue. See https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event. However, facebook/react#3964 seems to indicate that react *should* be treating onInput() the same as onChange(). Proof of concept (see `src/pages/testChange.tsx`) proves otherwise. Something in our particular setup, almost certainly to do with the way we are loading the initial state value from session/local storage, in combination with onChange() causes it to have buggy behavior.
onChange Note that onChange() was causing errors where the text field and text area inputs were failing to trigger on first deletion after refresh. Switching to onInput() fixed the issue. See https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event. However, facebook/react#3964 seems to indicate that react *should* be treating onInput() the same as onChange(). Proof of concept (see `src/pages/testChange.tsx`) proves otherwise. Something in our particular setup, almost certainly to do with the way we are loading the initial state value from session/local storage, in combination with onChange() causes it to have buggy behavior.
It is really aggravating, this "official answer". How presumptuous of them to call the HTML Spec official and consolidated event name a "misnomer". |
2024 and issue still exists, this one wasted a serious chunk of time, atleast I now have an answer but if I didnt trust facebook before I sure dont trust them now. Always follow the spec, there should be no alternative breaking change or not. |
Guys for people looking to do it with functions, expanding on Ettar solution, this seems to be working (here I am using MUI component, but input component works as well): import { TextField } from "@mui/material";
export default function MyCustomInput() {
const registerCallbacks = (element: HTMLInputElement | null) => {
if (element) {
element.onchange = (e) => console.log("onChange", (e.target as HTMLInputElement).value);
element.oninput = (e) => console.log("onInput");
}
};
return (
<TextField label="Outlined" variant="outlined" inputProps={{ref:registerCallbacks, onChange: undefined, onInput: undefined}} />
);
} |
It would be nice for the Forms doc to be more explicit about the fact that React's
onChange
supersedes, and should generally be used in place of, the DOM's built-inonInput
event. People might be used to usingonInput
instead for text inputs and textareas, since, with the raw DOM, the change event for these controls doesn't fire until the control loses focus.The text was updated successfully, but these errors were encountered: