Detect whether input element is focused within ReactJS
How can I detect whether an input element such as the following is currently focused within a ReactJS render function?
<input type="text" style={searchBoxStyle} placeholder="Search"></input>
Solution 1:
You can check against document.activeElement
as long as the input node is mounted and there is a reference to it:
const searchInput = React.useRef(null)
if (document.activeElement === searchInput.current) {
// do something
}
return <input type="text" ref={searchInput} />
Another way would be to add event listeners for the focus
and blur
events inside the input field:
const [focused, setFocused] = React.useState(false)
const onFocus = () => setFocused(true)
const onBlur = () => setFocused(false)
return <input type="text" onFocus={onFocus} onBlur={onBlur} />
Note that this will call a re-render each time the node is focused or blurred (but this is what you want, right?)
Solution 2:
I started with the answer given by David, where he describes two methods, and they both worked for me, but I had concerns about both:
-
On the first case it uses
findDOMNode
, what has some disadvantages: at minimum its use is discouraged, and it can easily be implemented in a way that it is considered an anti-pattern; and also it can make the code slower, by bypassing the virtual DOM and working with the DOM directly. -
On the second option, create and manage a component state only to find that answer seems too much work, can easily get out of sync, and can cause the component to re-render unnecessarily.
So after trying to explore the issue more, I came up with the following solution:
if (this.props.id === document.activeElement.id) {
// your code goes here
}
The same comment on David's answer applies:
You should not do this in the
render
method though, because the input node might not be mounted yet. Use a lifecycle method likecomponentDidUpdate
orcomponentDidMount
.
Advantages:
- uses the current component properties (which are immutable values)
- doesn't require state management, and therefore won't cause unnecessary re-rendering
- doesn't require DOM traversing, so performance should be as good as it gets
- doesn't require creating a component reference
Requirements:
- your component should have an
id
property that is passed to the form element you want to check (which is most likely the case anyway)