反应事件处理

时间:2017-08-30 12:26:05

标签: reactjs

考虑一个编辑框。用户键入一些文本。附加了一个按键处理程序,它可以执行以下操作:

setState({echo: this.state.echo + event.char})

是否有可能在初始状态{echo: “”}中,用户键入“a”然后“b”,React调用onKeyPress(“a”),调用setState({echo: “a”}),然后 - 在实际调用setState之前由React - React calls onKeyPress(“b”)申请?

你看到了问题,对吗? OnKeyPress(“b”)会看到与{echo: “”}相同的旧状态OnKeyPress(“a”),并会setState({echo: “”+“b”})发出setState({echo: “b”}),而我们显然需要{echo: “ab”}

  • 我的测试显示,在完全处理第一个setStat e之前,不会调用第二个事件处理程序。但是,与一些有记录的合同不同,可能会进行一些测试。
  • 我意识到这个问题有解决方案,比如使用表单setState( state => …)
  • 但我还是想知道:这种情况是否可能。也许保证合成事件处理程序只在所有挂起的setState处理(由前一个处理程序引起)完成后执行?如果是这样,我在哪里可以阅读一些证明?在Web上发布的某些手册或合格答案中的特定位置...或者,可能是相反的,这是正确的 - 没有这样的保证(但如果是这种情况,“简单”形式的setState肯定会导致错误和他们根本不应该允许这种形式。

3 个答案:

答案 0 :(得分:0)

setState将始终按顺序排列,但您提供的参数可以依赖于过去的状态。 setState次调用(例如来自您的两次按键)可以合并并在下一个周期调用。

这就是你在第二点提到的解决方案存在的原因,也是解决这个问题的正确方法。您在问题中描述的方式,简单地连接状态值和按下的键,正是文档advise against

答案 1 :(得分:0)

我建议您利用组件生命周期方法componentDidUpdate和componentWillUpdate。在这些方法之间,将有一个渲染周期。这使您可以响应已更改的内容。

尝试在捕获密钥时尝试将当前按键字符附加到现有字符串,尝试在componentDidUpdate()中附加字符。

在这种情况下,您只需将当前按键存储在状态(例如currKey)。然后在componentDidUpdate()中,您可以添加如下内容:

componentDidUpdate(prevProps, prevState) {
  const { currKey, echo } = this.state;
  if (currKey !== '') {
    this.setState({
      echo: echo + currKey, // append the current key to echo
      currKey: '' // reset the current key
    });
  }
}

此处的setState将触发另一轮更新,但在该轮中currKey将为空,这意味着在按下另一个键之前逻辑不会再次执行。

答案 2 :(得分:-1)

由于这是我第二次对类似问题没有明确答案,我只能推断出至少存在上述情景的理论可能性。然后我们在所有情况下都更好地遵循文档,并且只使用基于函数的setState来推断上一个状态的下一个状态。