Skip to content
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 does not work well with IE11 at Japanese IME. in React 15.4.0 #8423

Closed
mashimonator opened this issue Nov 26, 2016 · 7 comments
Closed

Comments

@mashimonator
Copy link

mashimonator commented Nov 26, 2016

untitled2

I'm trying to make a simple text box component with a suggestion feature.
However, in IE 11, there is an event that the Japanese IME conversion arbitrarily decides (I did not press the Enter key ...).
I examined it a little by myself, but this seems to have occurred only in IE 11, it seems that it has not occurred in other browsers such as Chrome and old Ver such as IE 10.
React version is 15.4.0.
There seemed to be similar issues in the past(https://github.com/facebook/react/issues/7027), but that bug has already been fixed.
Is this another bug? Or maybe I do not like how to make it?

/**
 * SuggestTextBox
 */
const SuggestTextBox = React.createClass({
	timer: null,
	getInitialState: function(){
		return {
			focus       : false,
			suggestList : [],
			value: ''
		};
	},
	/**
	 * getSuggestListFromApi
	 */
	getSuggestListFromApi: function(value){
		// Request API and get response
		Common.apiCall({
			type     : 'GET',
			url      : '/api/hoge',
			dataType : 'json',
			data     : {
				Keyword: value
			},
			cache    : false,
			callback : function(result){
				// set the state
				this.setState({
					suggestList: result.data.list,
					activeItem: null
				});
			}.bind(this)
		});
	},
	/**
	 * handleTextboxChange
	 */
	handleTextboxChange: function(e){
		this.setState({
			value: e.target.value,
			suggestList: []
		});
		if (this.state.focus) {
			if (e.target.value) {
				if (this.timer) {
					window.clearTimeout(this.timer);
				}
				this.timer = window.setTimeout(function(){
					this.getSuggestListFromApi(e.target.value);
				}.bind(this), 300);
			}
		}
	},
	/**
	 * handleFocus
	 */
	handleFocus: function(e){
		this.setState({
			focus: true
		});
	},
	/**
	 * getSuggestNodes
	 */
	getSuggestNode: function(){
		var listNode = this.state.suggestList.map(function(item, idx){
			return (
				<li
				  key={'fuga_suggestItem_'+item.id}
				  data-id={item.id}
				  data-name='fuga'
				  data-value={item.name}>
					{item.name}
				</li>
			);
		}.bind(this));
		if (listNode.length > 0) {
			return (
				<ul className="suggestList">
					{listNode}
				</ul>
			);
		} else {
			return null;
		}
	},
	render: function(){
		let suggestNode = this.getSuggestNode();
		return (
			<label>
				<input
				  type="text"
				  name="fuga"
				  value={this.state.value}
				  onChange={this.handleTextboxChange}
				  onFocus={this.handleFocus} />
				{suggestNode}
			</label>
		);
	}
});

https://jsfiddle.net/mashimonator/u3b0f1xj/1/

@mashimonator mashimonator changed the title onChange does not work well with IE11 onChange does not work well with IE11 at Japanese IME Nov 28, 2016
@mashimonator mashimonator changed the title onChange does not work well with IE11 at Japanese IME onChange does not work well with IE11 at Japanese IME. in React 15.4.0 Nov 30, 2016
@argelius
Copy link

I am having the exact same issue.

@mashimonator
Copy link
Author

mashimonator commented Feb 9, 2017

I solved this problem. I changed code this way 👇

/**
 * SuggestTextBox
 */
const SuggestTextBox = React.createClass({
	timer: null,
   :
	// add this code
	handleKeyDown: function(){
		if (this.timer) {
			window.clearTimeout(this.timer);
		}
	},
   :
	handleTextboxChange: function(e){
		if (this.timer) {
			window.clearTimeout(this.timer);
		}
		this.setState({
			value: e.target.value,
			suggestList: []
		});
		if (this.state.focus) {
			if (e.target.value) {
				if (this.timer) {
					window.clearTimeout(this.timer);
				}
				this.timer = window.setTimeout(function(){
					this.getSuggestListFromApi(e.target.value);
				}.bind(this), 300);
			}
		}
	},
   :
	render: function(){
		let suggestNode = this.getSuggestNode();
		return (
			<label>
				<input
				  type="text"
				  name="fuga"
				  value={this.state.value}
				  onChange={this.handleTextboxChange}
				  onFocus={this.handleFocus}
				  onKeyDown={this.handleKeyDown} />
				{suggestNode}
			</label>
		);
	}
});

@mashimonator
Copy link
Author

I found a better way.

	shouldComponentUpdate: function(nextProps, nextState){
		if (this.state.value == nextState.value) {
			return false;
		}
		return true;
	},

@makotot
Copy link

makotot commented Apr 11, 2017

I'm facing same issue. This can be reproduced in v15.5.3.

@tai2
Copy link

tai2 commented Oct 4, 2019

Here is a similar problem but a little different(not only for IE).

Code to reproduce: https://codesandbox.io/s/determined-ritchie-pn0b4

It is setting the state after onChange using setTimeout in this case. Technically, our product uses similar pattern so setting the value for a controlled input occurs sometime after onChange. So Japanese IME composition doesn't work properly. We are forced to use some dirty hack for workaround.

What I wonder now is whether the value state for input must be set in onChange handler directly by API design, or this is a subtle problem developers are unaware of.

@gaearon
Copy link
Collaborator

gaearon commented Mar 29, 2022

We've dropped IE from supported browsers in React 18 so this is unlikely to get fixed.
Sorry.

@gaearon gaearon closed this as completed Mar 29, 2022
@gaearon
Copy link
Collaborator

gaearon commented Mar 29, 2022

What I wonder now is whether the value state for input must be set in onChange handler directly by API design

Yes, controlled components must set it synchronously during onChange.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants