检测input元素是否聚焦在ReactJS中

如何检测当前是否在ReactJS渲染函数中集中了如下的input元素?

<input type="text" style={searchBoxStyle} placeholder="Search"></input> 

只要input节点被挂载并且有一个引用,就可以随时运行这样的事情:

 const ReactDOM = require('react-dom') if ( document.activeElement === ReactDOM.findDOMNode(this.refs.searchInput) ) 

您将不得不添加对input元素的引用:

 <input ref="searchInput" ... 

尽pipe如此,您不应该在render方法中执行此操作,因为input节点可能尚未安装。 使用像componentDidUpdatecomponentDidMount这样的生命周期方法。

另一种方法是为input字段中的focusblur事件添加事件侦听器:

 <input type="text" onFocus={this.onFocus} onBlur={this.onBlur}... 

然后在处理程序中设置状态并在渲染方法中检查该状态。

 onBlur: function() { this.setState({ focused: false }) }, onFocus: function() { this.setState({ focused: true }) }, render: function() { if ( this.state.focused ) { // do something } <input onFocus={this.onFocus} onBlur={this.onBlur}... } 

请注意,每次节点聚焦或模糊时,都会调用重新渲染(但这是您想要的,对吧?)

我从David提供的答案开始,在那里他描述了两种方法,他们都为我工作,但是我担心这两种方法:

  1. 在第一种情况下,它使用findDOMNode ,有什么缺点:至less它的使用是不鼓励的,它可以很容易地被实现,它被认为是反模式; 也可以通过绕开虚拟DOM并直接使用DOM来使代码变慢。

  2. 在第二个选项中,创build和pipe理组件状态只是为了发现答案看起来太多了,很容易失去同步,并可能导致组件不必要的重新渲染。

所以试图探索更多的问题,我想出了以下解决scheme:

 if (this.props.id === document.activeElement.id) { // your code goes here } 

大卫的答案也一样:

尽pipe如此,您不应该在渲染方法中执行此操作,因为input节点可能尚未安装。 使用像componentDidUpdate或componentDidMount这样的生命周期方法。

优点:

  • 使用当前的组件属性(什么是不可变的值)
  • 不需要国家pipe理,因此不会造成不必要的重新渲染
  • 不要求DOM横向,所以性能应该尽可能好
  • 它不需要创build组件引用

要求:

  • 你的组件应该有传递给你想要检查的表单元素的id属性(反正最有可能的情况是这样)