DEV Community

Chris Westbrook
Chris Westbrook

Posted on • Updated on

Managing Focus in React

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)

Collapse
 
dance2die profile image
Sung M. Kim

Thank you for the easy-to-digest post, Chris.

May I ask why you've used createRef over useRef? I've never done focus management thus not sure if createRef is preferred.

Collapse
 
westbrookc16 profile image
Chris Westbrook

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.

Collapse
 
nishchit6 profile image
Nishchith Rao

I tried with useRef..it does not seem to work...The current value is still null..Its not updated..Any solutions??
Thank you!!

Collapse
 
stomperhk profile image
Rafael

I don't know why, but refName.current.focus() just doesn't give me any visual result.

Collapse
 
sshakirbekovv profile image
Yerkebulan

hi

Collapse
 
sshakirbekovv profile image
Yerkebulan

test

Collapse
 
sshakirbekovv profile image
Yerkebulan

ddd

Collapse
 
sshakirbekovv profile image
Yerkebulan

php

Collapse
 
sshakirbekovv profile image
Yerkebulan

test

Collapse
 
sshakirbekovv profile image
Yerkebulan

PHP

Collapse
 
sshakirbekovv profile image
Yerkebulan

hh

Collapse
 
sshakirbekovv profile image
Yerkebulan

gg

Collapse
 
sshakirbekovv profile image
Yerkebulan

///