There are times when you may wish to set focus to a specific element in your react component, such as when the component first mounts, or perhaps after form submission. This is done relatively easily in react, and today I will show you how.
Ref api
In react, you can access a dom element easily using the ref attribute. Consider the followoing simple react component.
import React, { useRef } from 'react';
const HelloWorld = () => {
const mainRef = useRef(null);
return (
<div>
<h1 ref={mainRef} tabIndex="-1">
Hellow World
</h1>
Hello World
</div>
);
};
export default HelloWorld;
Notice in the above component, I created a variable with the name mainRef, though it could have been called anything. It simply has to be initialized with
useRef(null);
then when that variable is created, it can be referenced anywhere in the returned markup for the component using hte ref attribute. Here I set it on an h1 element, but it could have been set to anything. a form field, a div, a button, etc. I included a tabIndex of -1 on the h1 so that the element would be focusable, which we will handle in the next section.
setting focus with ref.current
Now we can set focus to a react ref by using an effect, like so:
useEffect(() => {
mainRef.current.focus();
}, [mainRef]);
```
This effect is pretty self-explanatory. it uses mainRef.current to get the dom element and then calls focus() on it. If it were an input, you could have set the value with mainREf.current.value="blah"; Anything you can do witha dom element you can do with ref.current.
#making things easier with a custom hook
You can make the task of setting focus on initial component mounting even easier with a custom hook. I created a custom hook that sets focus to a given ref as well as set the document title to a given string. It is below:
```jsx
import { useEffect } from 'react';
const useInitialfocus = (ref, title) => {
useEffect(() => {
ref.current.focus();
document.title = title;
}, [ref, title]);
};
export default useInitialfocus;
Here is the HelloWorld component with my useInitialFocus hook in use:
import React, { useRef } from 'react';
import useInitialFocus from './hooks/useInitialFocus';
const HelloWorld = () => {
const mainRef = useRef(null);
useInitialFocus(mainRef, 'Hello World');
return (
<div>
<h1 ref={mainRef} tabIndex="-1">
Hellow World
</h1>
Hello World
</div>
);
};
export default HelloWorld;
Make sure to change the import to useInitialfocus depending on your folder structure, etc. I hope this post gives you some incite on how to manage focus in react. Happy coding!!!
Top comments (13)
Thank you for the easy-to-digest post, Chris.
May I ask why you've used
createRef
overuseRef
? I've never done focus management thus not sure ifcreateRef
is preferred.No reason, I think I saw react.createRef somewhere and forgot about useRef. I have updated the post since useRef is more consistent. Thanks so much for the feedback.
I tried with useRef..it does not seem to work...The current value is still null..Its not updated..Any solutions??
Thank you!!
I don't know why, but refName.current.focus() just doesn't give me any visual result.
hi
test
ddd
php
test
PHP
hh
gg