reactjs / react-autocomplete

WAI-ARIA compliant React autocomplete (combobox) component
MIT License
2.17k stars 531 forks source link

can't type chinese when used in bootstrap modal #238

Closed rhqD closed 7 years ago

rhqD commented 7 years ago

when used in a bootstrap modal, it works totally fine with english input but when i try to type some Chinese characters it went like this:

rhq

then i looked into Autocomplete.js and the problem might be the handleChange Method. capture before call this.props.onChange, this.setState is excuted and it cause the component to render with current Props, and props.onChange will cause another render with a updated Props from its parent component. and those two renders does not always happen in a specific order which seems to be the cause of this problem, when used in a normal component the render triggered by setState happens after the one caused by props.onchange while in bootstrap modal they happens in reversed order.And after commet out "this.setState({ highlightedIndex: null }); " it works fine. then i made some changes to the handleChange callback to make sure they happens in the right order capture capture it also seems to solve the problem. but i can't solve this problem without modifying Autocomplete.js

CMTegner commented 7 years ago

I don't really understand what's causing this, or why that particular change fixes it.

when used in a normal component the render triggered by setState happens after the one caused by props.onchange while in bootstrap modal they happens in reversed order

It sounds like perhaps the modal component is causing a re-render that destroys the <input> element.

Can you create a reduced test case so we can debug this further?

rhqD commented 7 years ago

I have recreated the issue in a fiddle https://jsfiddle.net/barryRen/ae72rd1y/5/

CMTegner commented 7 years ago

I've spent some time trying to understand what's causing this, but I haven't found any conclusive evidence. This is what I know:

This change makes it work, and seemingly has no effect on other functionality:

--- a/lib/Autocomplete.js
+++ b/lib/Autocomplete.js
@@ -170,6 +170,7 @@ let Autocomplete = React.createClass({
     // If `items` has changed we want to reset `highlightedIndex`
     // since it probably no longer refers to a relevant item
     if (this.props.items !== nextProps.items ||
+      this.props.value !== nextProps.value ||
       // The entries in `items` may have been changed even though the
       // object reference remains the same, double check by seeing
       // if `highlightedIndex` points to an existing item
@@ -234,7 +235,6 @@ let Autocomplete = React.createClass({

   handleChange(event) {
     this._performAutoCompleteOnKeyUp = true
-    this.setState({ highlightedIndex: null })
     this.props.onChange(event, event.target.value)
   },

I'm hesitant to make this change before I understand what's actually going on. I'm afraid it may be due to a very subtle timing-issue, where the input is reset (by React, due to the nature of controlled inputs) just long enough for the browser to dismiss the Pinyin selector, before the user-controlled update comes along and results in the final render.

I made a repo which you can clone and npm install && npm start to reproduce the issue. It's there for anyone who has enough time and/or interest to attempt tracing the issue.

As a side note: I found an open issue in the React repo which seems to be the root cause of this problem.

CMTegner commented 7 years ago

@rhqD I reworked how the highlight logic works, and in the process I changed the handleChange event handler. My testing shows that the problem is resolved in 1.5.7, but please test to verify.