'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');
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
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 |