'How to set focus a ref using React-Hook-Form

How do you implement set focus in an input using React-Hook-Form, this is what their FAQ's "How to share ref usage" code here https://www.react-hook-form.com/faqs/#Howtosharerefusage

import React, { useRef } from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit } = useForm();
  const firstNameRef = useRef();
  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="firstName" ref={(e) => {
        register(e)
        firstNameRef.current = e // you can still assign to ref
      }} />
      <input name="lastName" ref={(e) => {
        // register's first argument is ref, and second is validation rules
        register(e, { required: true })
      }} />

      <button>Submit</button>
    </form>
  );
}

I tried set focusing the ref inside useEffect but it doesn't work:

useEffect(()=>{
   firstNameRef.current.focus();
},[])

Neither does inside the input:

<input name="firstName" ref={(e) => {
    register(e)
    firstNameRef.current = e;
    e.focus();
}} />


Solution 1:[1]

You can set the focus using the setFocus helper returned by the useForm hook (no need to use a custom ref):

 const allMethods = useForm();
 const { setFocus } = allMethods;

 ...

 setFocus('inputName');

https://react-hook-form.com/api/useform/setFocus

Solution 2:[2]

Are you using Typescript?

If so, replace...

const firstNameRef = useRef();

With...

const firstNameRef = useRef<HTMLInputElement | null>(null);

Solution 3:[3]

useEffect(() => {
if (firstNameRef.current) {
      register(firstNameRef.current)
      firstNameRef.current.focus()
    }
}, []);

<input name="firstName" ref={firstNameRef} />

Got this from : https://github.com/react-hook-form/react-hook-form/issues/230

Solution 4:[4]

If you using Version 7, you can check this link in the docs

https://www.react-hook-form.com/faqs/#Howtosharerefusage

Solution 5:[5]

I think you can simply use ref={(el) => el.focus()} to set the focus. The catch here is to make sure no other element within your page is also setting focus right after that el.focus() call.

Solution 6:[6]

I can't comment (I don't have enough reputation), but without setting a timeout, setFocus didn't work. After adding a simple timeout from Subham's answer, it worked like a charm!

PS: Even adding a timeout of 0: setTimeout(() => setFocus(fieldName), 0) works. Can anyone explain?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Bryce
Solution 2 Steve S
Solution 3
Solution 4 Maged Mohamed
Solution 5 Chuma
Solution 6