使用异步onChange处理程序将React.js输入游标重置

时间:2017-04-09 11:55:42

标签: reactjs asynchronous input cursor reset

如果我有以下反应成分:

class Cmpt extends Component {
   setValue( e ) {
     this.setState({ value : e.target.value });
   }
   render() {
     return <input value={this.state.val} onChange={this.setValue.bind(this)}/>
   }
}

现在这可以正常工作,编辑文本不会将光标重置到输入的末尾。如果我修改它以使setState在异步中发生,则会发生游标重置:

class Cmpt extends Component {
   setValue( e ) {
     setTimeout( () =>
       this.setState({ value : e.target.value }) );
   }
   render() {
     return <input value={this.state.val} onChange={this.setValue.bind(this)}/>
   }
}

显然,修复方法是不同步调用setState - 但我不明白为什么异步版本无法正常工作。在我的脑海中,事件链如下:

  1. 用户在输入字段中添加字符,将其从ACD更改为A B CD
  2. 输入DOM节点的值更改为ABCD以反映此
  3. 一段时间过去了
  4. 调用
  5. setState - 将反应组件的状态从ACD更改为ABCD
  6. 触发render调用 - React diffing算法将DOM节点值(ABCD)与this.state.value(ABCD)的值进行比较。它看到两者都是相同的,因此不会触发重绘并保留光标
  7. 显然我的心智模型是错误的,因为正在触发重绘 - 导致光标重置。

    请有人解释原因吗?

    谢谢!

2 个答案:

答案 0 :(得分:0)

状态更改将始终触发新的render调用。之后,React自己决定重新渲染什么。但它总会通过改变状态来触发。即使你这样做

this.setState({})

它将调用render方法。

答案 1 :(得分:0)

对不起家伙,发现一个重复的问题回答了我的问题:

In ReactJS, why does `setState` behave differently when called synchronously?

我无法弄清楚如何将自己的问题标记为副本:(

我对事件顺序的心理模型是错误的。显然,在每个事件处理程序结束时,react会触发同步重新渲染,因此在DOM发生变化后,渲染会被称为 ,而之前的会发生变化 - 导致重绘和光标重置

全部谢谢

Ť