-
Notifications
You must be signed in to change notification settings - Fork 46.8k
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
OnChange randomly misses keys on IE if typing very quickly #7027
Comments
It's really weird, I don't see anything wrong with your code... this should not happen. So this should indeed be a bug. I can't really wrap my head around how or why this behavior is happening, will be interesting to see what's causing it. Really interesting. |
cc @jquense I'm sure you'll love this ;) |
interesting... @pasieronen could you possibly try using React master and see if it's still a problem? i also wonder if it happens on older ie..hmm |
IE11 affected. |
It looks to me like IE11 is setting the value as soon as the user types a keystroke, and enqueuing the event handler. As a result, the timeout callback calls setState, which causes a reconciliation, which resets the input value, which causes the Notice that if you replace the To me, this looks like a bug in IE (setting the value should happen immediately prior to calling onChange) rather than a bug in React. |
@jimfb Anyway, after some debugging I don't really feel a lot smarter. However, it seems the root of the problem may be related to the keyup/keydown/etc handling of ChangeEventPlugin in a sense. To accurately reproduce the problem, hold down a key and then press a different one without letting go of the first and you have reproduced the problem, which may further hint at the underlying problem. It's also worth noting that in that instance, logging |
the most recent reason is that it fires too often and inconsistently. changing a placeholder for instance fires onInput, re-using the polyfill was a quick way to fix it though it seems to probably have cause more bugs than fixed (browsers!). master listens for both onChange and onInput and dedupe em, which is (hopefully) a more correct solution what I've learned is that the polyfill doesn't scale super well to ie11 which being the first "good" IE seems to break a bunch of MS-isms that make it work in ie8-9. Also there are probably a bunch of these bugs in old IE too but didn't notice them because of lower market share? |
Is there any temporal workaround for that, that could be applied in the app? |
I think you could update the value of your controlled component during your timeout/setState call, as I mentioned earlier...
Alternatively, you could restructure your code to avoid calling setState in an asynchronous/timeout callback. I think if you call setState() only in the event handler, things will work without an issue, since the problem is a race condition between the characters typed and the setState calls. I realize neither of those are particularly good workarounds. I would also recommend filing a bug with the microsoft/IE11 team, since this looks like an IE bug to me. Setting the node's value and firing the event handlers should be synchronous. Other timers/events (like setTimeout) should not be injected between those two operations. This assumes that my understanding of the issue is correct. If you can reproduce the bug without React (should be possible, just do whatever React is doing, probably just setting the node's value directly in the setTimeout call would be sufficient), that will likely help the IE team narrow down the issue. On our end, I'm not sure there is much we could do about this problem. At first glance it appears to be a browser bug, though I'd love to be proven wrong (it is conceivable this is a React bug). Assuming it is a browser bug, we might be able to mitigate the problem, but we may not be able to eliminate it entirely. In years of React, you're first person to run into this, so it is probably not the highest item on our todo list, but I do understand that it is annoying/frustrating to run into things like this. Unfortunately, browser bugs are often difficult for us to fix on our end. |
@jimfb Considering that
While true, that doesn't take into consideration any unrelated asynchronous updates that may happen elsewhere in the application, which would cause it to update and rerender. Outside of your control.
I'm not convinced IE11 is really at fault here, as far as I can tell we have a hacky workaround for reimplementing oninput which may rely on very specific browser behavior of keydown/keyup/etc (keydown fires before value is updated). Determining the exact fault or adding the native oninput (which seems to work) into the mix may solve the problem. I don't have any faith in IE11 shipping a fix for this any time soon (or ever, and everyone also updating to it) and we're bound to support it for a very long time. |
@jimfb @syranide The thing is that react 0.14.8 handles this correctly. I have two demos with the exact code and different versions of react. One is buggy in IE11 and one is not. |
Oh, weird, ok, so this was broken in 0.14.3, fixed in 0.14.8, and broken again in 15.1.0, is that correct? I just tried on my master fiddle (http://jsfiddle.net/s2ot6w4z/) and it seemed to be fine. @smashercosmo, can you verify that it is fixed in the fiddle? http://jsfiddle.net/s2ot6w4z/ |
@jimfb I confirm. Latest react doesn't have this speedtyping issue. Tested both demos (yours and mine). |
master does listen for onInput; if IE is correctly reporting there this should be fixed. like I said above it just turns out that the polyfill we have for onInput actually has a lot of edge cases no one noticed :P (and it's assumptions don't quite work on ie11) |
Ok, we close out bugs when they're fixed in master. This fix will be part of a future release. |
I know this bug has been closed by changes to master, but it's still affecting the 15 branch. I don't think that @syranide is correct about this being an IE11 bug, he correctly points out it seems to be caused by making asynchronous updates to state, but I think the cause of the bug is that react uses Consequently any state changes triggered in response to a change event in IE11 are racy, and may cause input to be lost. |
I would assume that since the fix was on master in mid-June that it went out with |
@HankMcCoy master is v16.0.0 so any v15 wouldn't include them |
Our company works in the construction industry and therefore has a lot of clients on old machines with IE11 filling out massive forms, so this is a pretty substantial problem for us. Do you know where in the codebase the fix was applied? We're seriously considering temporarily forking in order to cherry-pick the fix for this, if that is even remotely feasible. And thanks for the ludicrously fast reply, @jquense! |
I forget the PR number, but you can npm install react@next that might do it for you. |
Sadly react@next is 15.3, so still no fix. :/ Is this the PR in question: #5746? I cherry picked that change onto the |
I believe that's the only one. I do think that there is a releases v16 alpha perhaps. |
We encounter the same issue here; just wondering when v16.0.0 is due to be released? |
We are seeing the same issue. It's a pretty big deal for us since our users are on IE11 for enterprise policy reasons. This bug renders our app almost unusable to them. |
Would just like to back up @PenguinOfThunder. Back-porting this fix to the 15 release would be immensely helpful. As it is this is screwing us over pretty royally with customers stuck on IE11 (of which there are, unfortunately, many). |
For now, the best I can suggest is to build from master yourself, or grab a nightly master build here: http://react.zpao.com/builds/master/latest/. Obviously they are not guaranteed to be stable. (Please make your own copy, don’t link to @zpao’s website 😉 ) |
I've tested react On another note, we tried replacing |
@JohanBengtsson I did not test my tempory fix on IE10 (yes like everyone I try to step away IE as much as I can 😄) but did you set Here is my import React, {
Component,
PropTypes
} from 'react';
import shallowCompare from 'react-addons-shallow-compare';
class TextInput extends Component {
constructor(props) {
super(props);
this.state = { stateValue: '' };
this.handlesOnChange = this.handlesOnChange.bind(this);
this.timer = null;
}
componentWillReceiveProps(nextProps) {
const { stateValue } = this.state;
const { value } = nextProps;
if ((value !== stateValue) && stateValue.length === 0) {
this.setState({stateValue: value});
}
}
shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}
componentWillUnmount() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
}
render() {
const {label, id} = this.props;
const { stateValue } = this.state;
return (
<div className="form-group">
<label
className="control-label"
htmlFor={id}>
{label}
</label>
<div>
<input
className="form-control"
id={id}
type="text"
// value={value}
defaultValue={stateValue}
onInput={this.handlesOnChange}
/>
</div>
</div>
);
}
handlesOnChange(event) {
event.preventDefault();
this.setState({stateValue: event.target.value});
this.setTimerBeforeCallback(event.target.value);
}
setTimerBeforeCallback(value) {
const { onChange, delay } = this.props;
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
this.timer = setTimeout(
() => onChange(value),
delay
);
}
}
TextInput.propTypes = {
label: PropTypes.string.isRequired,
id: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
delay: PropTypes.number
};
TextInput.defaultProps = {
delay: 200
};
export default TextInput; |
@MacKentoch Thanks for the tip! Yeah we've got it working well for IE11 now with a short term work around of changing to |
I switched to using onInput, this then broke IE10 & IE9. The following disgusting hack is what I have ended up doing until it's fixed, YUCK.
|
I'd also want to follow up to my post from August last year. It's now been 7 months of waiting :( Last year I hoped that 16.0 is not too far away. However that assumptions seems to be wrong. If this wouldn't be such a super yucky thing I'd be ok with it but I constantly have to answer the question, why we can't fix that. |
@frontendphil maybe note that in #8575 :) |
I had the same problem. I solved it by using a similar solution as @MacKentoch suggested (using |
There are various better sources for this fix than this repo. See discussion on facebook/react#7027 and various react-autosuggest forks. We might want to detect IE11/Edge rather than doing this across the board but this is a start (what about IE < 11?).
Temporary fix for issue here: facebook/react#7027
@pasieronen It's fixed in React version 15.6.1 |
@bbarnell Upgrading to |
@programmist My site is now working without changing any code other than the version: |
Unsubscribe
Sent from ProtonMail mobile
…-------- Original Message --------
On Sep 15, 2017, 8:22 PM, Jonathan Ankiewicz wrote:
Where is Microsoft IE developers? Do they not use the internet like the rest of us? Do they not see the constant issues IE has?
I'm running into the same issues in production. I'll try pushing for the React update first
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, [view it on GitHub](#7027 (comment)), or [mute the thread](https://github.com/notifications/unsubscribe-auth/AbBJ5tdrKcH2ARRb3r-aeydbrvZDs2k0ks5sisBygaJpZM4I0ONh).
|
This seems to be broken in React 16.4.1 - I am experiencing this same bug in IE11 |
This comment has been minimized.
This comment has been minimized.
File a new issue with details please. Thanks. We don't track closed issues. |
I have a simple search bar (controlled text input) with autocomplete.
When I type text very quickly, I do get onKeyDown events, but every now and then, the corresponding onChange event goes missing. For example, if I type "foobar", the input field may end up showing "foobr".
This happens only on IE (tested with IE11 on Windows 7), and I have not seen this on any other browser.
Here's a fiddle showing the issue: https://jsfiddle.net/zjfbow3w/3/ and a log:
Note that onKeyDown handler sees that "a", but not the onChange handler.
The fiddle includes a timer (which in real code triggers an AJAX call), which is somehow important for this issue -- if I remove the timer, I cannot reproduce this issue any more.
The React version in the fiddle is 15.1.0 (but this happens on 0.14.3, too).
The text was updated successfully, but these errors were encountered: