【发布时间】:2015-08-17 14:46:01
【问题描述】:
如何检测如下输入元素当前是否聚焦在 ReactJS 渲染函数中?
<input type="text" style={searchBoxStyle} placeholder="Search"></input>
【问题讨论】:
标签: javascript node.js reactjs
如何检测如下输入元素当前是否聚焦在 ReactJS 渲染函数中?
<input type="text" style={searchBoxStyle} placeholder="Search"></input>
【问题讨论】:
标签: javascript node.js reactjs
只要输入节点已挂载且有引用,您就可以检查document.activeElement:
const searchInput = React.useRef(null)
if (document.activeElement === searchInput.current) {
// do something
}
return <input type="text" ref={searchInput} />
另一种方法是在输入字段中为 focus 和 blur 事件添加事件侦听器:
const [focused, setFocused] = React.useState(false)
const onFocus = () => setFocused(true)
const onBlur = () => setFocused(false)
return <input type="text" onFocus={onFocus} onBlur={onBlur} />
请注意,每次节点聚焦或模糊时,这都会调用重新渲染(但这正是您想要的,对吧?)
【讨论】:
findDOMNode 已移至ReactDOM 下
refs 这种方式,应该使用新的 React.createRef() 功能。更多信息:reactjs.org/docs/refs-and-the-dom.html
refs.current.hasFocus这样的东西
document.activeElement 与您的参考进行比较:document.activeElement === this.ref.current
我从大卫给出的答案开始,他描述了两种方法,它们都对我有用,但我对这两种方法都有顾虑:
在第一种情况下,它使用findDOMNode,有一些缺点:至少不鼓励使用它,并且可以很容易地以一种被认为是反模式的方式实现;而且它还可以通过绕过虚拟DOM并直接使用DOM来使代码变慢。
在第二个选项中,创建和管理组件状态只是发现答案似乎工作量太大,很容易不同步,并且可能导致组件不必要地重新渲染。
所以在尝试更多地探索这个问题之后,我想出了以下解决方案:
if (this.props.id === document.activeElement.id) {
// your code goes here
}
对大卫的回答也有同样的评论:
您不应该在
render方法中执行此操作,因为输入节点可能尚未安装。使用像componentDidUpdate或componentDidMount这样的生命周期方法。
优点:
要求:
id 属性,该属性将传递给您要检查的表单元素(无论如何,这很可能是这种情况)【讨论】:
使用钩子:
首先你创建并初始化你的引用
const yourElement = useRef(null)
然后你用你刚刚创建的引用标记你的元素:
<div ref={yourElement}>Im an DOM node</div>
然后,您使用此逻辑来比较 document.activeElement 文档属性是否等于您引用的 DOM 节点
yourElement.current === document.activeElement
【讨论】:
使用钩子的方法要简单得多。
进行导入
import React, {useState} from "react";
定义
const [isMyInputFocused, setIsMyInputFocused] = useState(false);
在您选择的输入中添加
onBlur={() => setIsMyInputFocused(false)}
onFocus={() => setIsMyInputFocused(true)}
从现在开始,您可以随意访问isMyInputFocused。
【讨论】:
使用功能组件可以判断当前输入是否有焦点:
import React from "react";
export default function App() {
const ref = React.createRef(null);
const handleMouseOut = (currentRef) => {
if (document.activeElement === currentRef) {
console.log("Yesss");
}
};
return (
<div className="App">
<input
type="text"
ref={ref}
onMouseOut={() => handleMouseOut(ref.current)}
/>
</div>
);
}
【讨论】:
根据您想要做什么,您可以使用onFocus (React 17) 或 onBlur (React 16) 来实现当这些事情成为焦点时您想要的功能。
【讨论】: