If you had 500 components, each with a ref
, how would you find which component has the user's focus? All components with a ref
are focusable elements like <input />
, <textarea />
, etc. For simplicity, all of the refs
are accessible from a single top-level component.
This is very simple if your React components have classNames
- but if you want to find the ref
of a document.activeElement
, if there some way to achieve that without having to resort to classNames?
To touch on why we don't have classNames
, we're using JSS
via emotion
. To have to manually assign everything a className
just for this purpose would be rather absurd. No obvious alternative has occurred to me.
You can check the current active element in the DOM using the chrome devtools by going to Console > Create Live Expression (the eye icon) and typing document. activeElement .
Open the console by either right-clicking and inspecting an element or by opening the toolbar by clicking View > Developer > JavaScript console. The Components tab will show the current React component tree, along with any props, state, or context.
The activeElement property returns the currently focused element in the document. Note: This property is read-only. Tip: To give focus to an element, use the element .focus () method. Tip: To find out if the document has focus, use the document.hasFocus () method.
React .focus (). A simple explanation of .focus () use in… | by James Dorr | The Startup | Medium Many React tutorials describe long processes that lead to the successful use of .focus () with React. The .focus () method tells the browser which element is being acted on, similar to .click () or an actual click.
The document.activeElement property helps us to access the element that is currently focused in the document. It also shows body or null if there is no focused element. In this example, we are logging the currently selected element tag name.
When we pass a ref prop to an element, e.g. <input ref= {myRef} />, React sets the .current property of the ref object to the corresponding DOM node. We passed an empty dependencies array to the useEffect hook, so it's only going to run when the component mounts.
This may be a good use case for a custom hook that hooks into the native DOM methods to track focus events and then returns the active element. This will log the active element every time a new element receives focus:
const useActiveElement = () => {
const [active, setActive] = useState(document.activeElement);
const handleFocusIn = (e) => {
setActive(document.activeElement);
}
useEffect(() => {
document.addEventListener('focusin', handleFocusIn)
return () => {
document.removeEventListener('focusin', handleFocusIn)
};
}, [])
return active;
}
const App = () => {
const focusedElement = useActiveElement();
useEffect(() => {
if (focusedElement) {
focusedElement.value && console.log(focusedElement.value);
}
console.log(focusedElement);
}, [focusedElement])
return (
<div>
<input type="text"/>
<button>Button</button>
</div>
)
}
However, correlating this element with your refs could prove tricky, as you'd need to keep a collection of the refs to search through which would probably involve giving each element its own callback ref to store in an Array or something similar. But depending on what you need to do with the element once it's focused, it may not be necessary. For example, the code I posted above will log the value of the input if it exists. It would help to know more specifically what your use case is for tracking this data.
Do you want something like that, react gives you an option to track/focus using ref
import React, { Component } from "react";
class App extends Component {
constructor(props) {
super(props);
// create a ref to store the textInput DOM element
this.textInput = React.createRef();
this.button = React.createRef();
this.textarea = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// this.textInput.current.focus();
this.button.current.focus();
// this.textarea.current.focus();
}
render() {
return (
<div>
<input type="text" ref={this.textInput} />
<button ref={this.button}>something</button>
<textarea ref={this.textarea}></textarea>
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
export default App;
You can get a detail here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With