我正在创建一个小实用程序,我需要调用setState
延迟到输入的onChange
处理程序触发的下一个tick。下面是一个显示基本概念的简单片段。
https://jsfiddle.net/samuelsimoes/q3p44sz1/
class MyComponent extends React.Component {
constructor () {
super(...arguments);
this.state = {};
}
onChange (value) {
setTimeout(v => {
this.setState({ name: v });
}.bind(this, value), 0);
}
render () {
return (
<div>
<input
type="text"
value={this.state.name}
onChange={evt => this.onChange(evt.target.value)} />
</div>
);
}
};
ReactDOM.render(
<MyComponent/>,
document.getElementById("app-container")
);
如果您在Mac OS上的浏览器中运行此代码段并尝试键入带有重音符号的某个字母,则会在每个浏览器上产生不同的尴尬行为。在Chrome上,重音仅适用于第一次,不再应用重音(请查看下面的gif)。在Firefox上,重音和字母不会出现。
你们对此有什么线索吗?
p.s。:我在React 0.13,0.14和15.0.2上测试了这种行为。
答案 0 :(得分:2)
基本上你不应该推迟setState
。在这种情况下,React不能正常工作。
看:https://github.com/facebook/react/issues/6563
发生了什么:
我们假设你按下A
字母。
当您在字段中触发onChange
时,React会处理所有状态突变。
在状态变异过程之后,React执行DOM diff以更新组件,在此阶段,此字段的状态值为空值,因此React执行node.value = ""
。
在下一个刻度线上,我们将延迟setState
与A
一起应用字母node.value = "A"
。
这种行为打破了MacOS上的浏览器,它们取代了#34;中间状态&#34;到键入的重音,防止用户键入突出的字符。
所以,遗憾的是没有解决方案。