Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>    
like image 457
HelpMeStackOverflowMyOnlyHope Avatar asked Jun 03 '15 11:06

HelpMeStackOverflowMyOnlyHope


People also ask

How do you know which element is focused?

Syntax: var ele = document. activeElement; Return value: It returns the currently focused element in the document.

What is focus () in React?

To focus input when another element is clicked in React: Set the ref prop on the input element. Set the onClick prop on the other element. When the other element is clicked, focus the input, e.g. ref.

How do you check if text input is focused react native?

To check when the focus is lost in a React Native TextInput, we can set the onBlur prop to a function that runs when focus is lost. to set the onBlur prop to a function that logs 'focus lost' when we move focus away from the text input.

How do you get focus on React?

If you just want to make autofocus in React, it's simple. While if you just want to know where to put that code, answer is in componentDidMount(). In most cases, you can attach a ref to the DOM node and avoid using findDOMNode at all.


2 Answers

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?)

like image 160
David Hellsing Avatar answered Oct 14 '22 17:10

David Hellsing


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:

  1. 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.

  2. 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 like componentDidUpdate or componentDidMount.

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)
like image 20
Marcos Abreu Avatar answered Oct 14 '22 16:10

Marcos Abreu