Proposition about onInput/onChange
Hi :)
In ReactDom we can find:
function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
return getInstIfValueChanged(targetInst);
}
}
Why not adding an extra condition here like:
function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
if ((!React.$$useRealOnChange && topLevelType === TOP_INPUT) || topLevelType === TOP_CHANGE) {
return getInstIfValueChanged(targetInst);
}
}
By checking React.$$useRealOnChange in this function, a user could add this line:
React.$$useRealOnChange = true;
anywhere in their code (before or after including ReactDom) to find back the more native behavior.
I'm sorry in advance if this proposition has already been proposed
If I understand your proposed solution correctly, React.$$useRealOnChange would be a global variable that would change the behavior of onChange in code such as <input onChange={event => handleChange(event)} />. The goal is to easily listen to the browser’s built-in change event.
I, too, wish that React allowed me to listen to the native change event. However, I have concerns about that specific solution. I worry that adding a global variable like React.$$useRealOnChange would cause surprising bugs and complicate testing. If you set React.$$useRealOnChange to true in one part of the code, it could affects parts of the code that were written assuming a value of false for it.
I favor the solution proposed by this older issue: #14857 “Easily handle browser 'change' events”. That issue proposed supporting a new attribute on input elements that act like a browser-native onchange attribute. It suggested these names as possibilities:
- onChangeAndBlur
- onChangeNative
- onChangeCompleted
- onCompleteChange
That issue was automatically closed for being “stale”, so perhaps this issue should become the new active issue about accessing the browser-native onchange.
would cause surprising bugs and complicate testing
Indeed yes, but any dependence could correct their code by changing the onchange by oninput, this would not break anything, i suppose. Anyway changing this setting would be something advanced maybe react could console.warn us at each load in dev mode idk.
I have to admit, the other solution is safer you're right.
But even without adding a secret variable, why not just expose the function responsible of that and let the possibility to redo the function as we wish.
Hey hey! Could you add an example in CodeSandbox? That would really help us look into this :)
@rachelnabors Here’s an example I made that demonstrates the desired behavior, React not providing access to that behavior, and the way I personally wish React would give us access to that behavior:
CodeSandbox demo requesting native onchange in React
Mirror of that demo page
As CodeSandbox is a third-party site I am unfamiliar with, I don’t trust it to stay up forever, so here’s a mirror of the important parts of that demo page:
public/index.html
<div> <script> function handleNativeOnChange(event) { console.log("native change event fired", event.value); } </script> <h2>Demo of native <code>onchange</code> attribute</h2> <input type="number" onchange="handleNativeOnChange(this)" /> </div>
Demo of native
onchangeattributeThe above number-type
inputelement logs a message when itschangeevent is fired. Such an event is fired when a change is committed. The exact conditions of the event firing depend on the type of input element and possibly the browser, but in my testing with this particularinputelement, thechangeevent seems to fire when any of the following happen:
- The field is blurred after its value was changed.
- The user presses Enter/Return on the keyboard after changing its value.
- The user increments or decrements the number in the field by pressing Up or Down on the keyboard.
src/App.js
export default function App() { function handleOnChange(event) { console.log("React change event handler called", event.target.value); } return ( <div className="App"> <h2> Demo of React <code>onChange</code> attribute </h2> <input type="number" onChange={handleOnChange} /> </div> ); }
Demo of React
onChangeattributeThe above number
inputlogs a message on everyinputevent, rather than only onchangeevents. This is because React’sonChangeattribute works the same as anonInputattribute.Requested feature for React
It’s too late to redefine React’s
onChangeattribute, but can we add a way to get the same behavior as HTML’sonchangeattribute without manually handling all the cases listed in that section?Multiple possible solutions are discussed in React issue #19150, but the idea I currently favor is supporting a new attribute
onChangeCompletedoninputelements. If such an attribute existed, the following commented-out input element would work the same as in the native demo:
<input type="number" onChangeCompleted={handleOnChange} />
Thanks so much for explaining your approach to me! Unfortunately, a global configuration option would force every third party component author to be compatible with both modes—which we feel would put too much strain on the ecosystem. There have been previous discussions, and if you have feedback, we'd love for you to join the conversation!
@rachelnabors
Unfortunately, a global configuration option would force every third party component author to be compatible with both modes
I think you overlooked a large part of the demo I provided. I was not suggesting a global configuration option—that was only @mr21’s idea. In my demo, I suggested adding a new attribute to React input elements, onChangeCompleted. Such an addition would be backwards-compatible because currently that attribute is ignored (and logs a warning that it is unknown).
There have been previous discussions, and if you have feedback, we'd love for you to join the conversation!
Discussing how to listen to input change events with React is a bit confusing because there have been multiple solutions discussed in multiple places:
- #14857 (closed) suggested the same thing I want to suggest, adding a new attribute such as
onChangeCompleted. That issue was automatically closed due to inactivity. - #19150 (open) (this issue) suggested a global configuration option
$$useRealOnChange.- I then suggested an alternative, adding a new attribute such as
onChangeCompleted.
- I then suggested an alternative, adding a new attribute such as
- #9657 (open) suggested a backwards-incompatible change to the existing attribute
onChange.- Later comments in that issue discuss the idea of a new attribute such as
onEveryChange, but the new attribute would be in addition to the backwards-incompatible change toonChange.
- Later comments in that issue discuss the idea of a new attribute such as
In which places would you like me to discuss my preferred solution of adding a backwards-compatible new attribute such as onChangeCompleted? You suggested #9657, but I’m thinking it would make the conversation clearer if you reopened issue #14857, or if I created a new issue and posted links to it in the other issues.
I think you overlooked a large part of the demo I provided.
I believe @rachelnabors was responding to the original post proposal. Yours is indeed different.
In which places would you like me to discuss my preferred solution of adding a backwards-compatible new attribute such as onChangeCompleted?
If you have a fully-formed proposal, http://github.com/reactjs/rfcs would be a good place to submit it as a PR.
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
Bump
Bump
+1 for onChangeNative, Redux goes ballistic when you dispatch actions on each key stroke 😟
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
Bump. This problem has not been solved yet: in React’s documentation for onChange there is still no mention of an alternative attribute (which would have a name like onChangeCompleted or onChangeNative) that uses the browser’s native onchange event handler.
Definitely a bug IMO Broken useful native behavior of browser's tag without smooth backward compatible/workarounds ( Sad that this issue does not fixed yet
unsubscribe https://github.com/notifications/unsubscribe-auth/AUFSVP5YS762KBURJRPQK33WRI77ZANCNFSM4OBGJHDQ
On Sun, Jan 8, 2023 at 8:07 AM Pavel @.***> wrote:
Definitely a bug IMO Broken useful native behavior of browser's tag without smooth backward compatible/workarounds ( Sad that this issue does not fixed yet
— Reply to this email directly, view it on GitHub https://github.com/facebook/react/issues/19150#issuecomment-1374706395, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUFSVP5YS762KBURJRPQK33WRI77ZANCNFSM4OBGJHDQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>
throwing in a plea for some kind of "onCommit", "onChangeComplete" or similar that utilizes the native change event.
obviously one could trivially add a custom handler using the addEventListener, but like all DOM events, it won't bubble up the React Tree like a synthetic event would.
or if there was a way to add a custom SyntheticEvent that will bubble up the React Tree instead of the DOM tree, that'd work to.
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
Bump
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
This issue has been automatically marked as stale
I hate bots, please don't close this issue