检测输入元素是否在ReactJS中聚焦

Hel*_*ope 41 javascript node.js reactjs

如何检测诸如以下的输入元素当前是否聚焦在ReactJS渲染函数中?

<input type="text" style={searchBoxStyle} placeholder="Search"></input>   
Run Code Online (Sandbox Code Playgroud)

Dav*_*ing 57

只要输入节点已安装并且有对它的引用,您就可以随时运行此类操作:

const ReactDOM = require('react-dom')

if ( document.activeElement === ReactDOM.findDOMNode(this.refs.searchInput) )
Run Code Online (Sandbox Code Playgroud)

您必须添加对input元素的引用:

<input ref="searchInput" ...
Run Code Online (Sandbox Code Playgroud)

但是,您不应该在render方法中执行此操作,因为输入节点可能尚未安装.使用像componentDidUpdate或的生命周期方法componentDidMount.

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

<input type="text" onFocus={this.onFocus} onBlur={this.onBlur}...
Run Code Online (Sandbox Code Playgroud)

然后在处理程序中设置状态并在render方法中检查该状态.

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}...
}
Run Code Online (Sandbox Code Playgroud)

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

  • `findDOMNode`后来被移到`ReactDOM`下 (4认同)
  • 对于多年后发现这篇文章的人:在 React 16.x 及更高版本中,不再建议以这种方式使用“refs”,应该使用新的“React.createRef()”功能。更多信息在这里:https://reactjs.org/docs/refs-and-the-dom.html (2认同)

Mar*_*reu 14

我从大卫给出的答案开始,他描述了两种方法,他们都为我工作,但我对两者都有所顾虑:

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

  2. 在第二个选项中,创建和管理组件状态只是为了发现答案似乎太多工作,很容易失去同步,并且可能导致组件不必要地重新呈现.

因此,我试图探索更多问题,提出以下解决方案:

if (this.props.id === document.activeElement.id) {
  // your code goes here
}
Run Code Online (Sandbox Code Playgroud)

同样评论大卫的答案适用:

但是,您不应该在render方法中执行此操作,因为输入节点可能尚未安装.使用componentDidUpdate或componentDidMount之类的生命周期方法.

好处:

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

要求:

  • 你的组件应该具有id传递给你想要检查的表单元素的属性(无论如何最有可能的情况)


dea*_*fry 10

使用钩子有一种更简单的方法。进行导入:

import React, {useState} from "react";
Run Code Online (Sandbox Code Playgroud)

定义:

const [isMyInputFocused, setIsMyInputFocused] = useState(false);
Run Code Online (Sandbox Code Playgroud)

在您选择的输入中只需添加:

onBlur={() => setIsMyInputFocused(false)}
onFocus={() => setIsMyInputFocused(true)}
Run Code Online (Sandbox Code Playgroud)

从现在开始,您可以isMyInputFocused随心所欲地访问。

  • 这是一个“伪焦点”,并且无法很好地扩展:例如:如果有 10 个输入,您将必须提升此状态并开始管理引用,否则此状态将需要应用于每个输入,并且存在风险不同步 (4认同)

Rol*_*ubó 6

使用钩子:

首先,您创建并初始化您的参考

const yourElement = useRef(null)
Run Code Online (Sandbox Code Playgroud)

然后你用你刚刚创建的引用标记你的元素:

<div ref={yourElement}>Im an DOM node</div>
Run Code Online (Sandbox Code Playgroud)

然后,您使用此逻辑,因为您需要比较document.activeElement文档属性是否等于您引用的 DOM 节点

yourElement.current === document.activeElement
Run Code Online (Sandbox Code Playgroud)