Having such simple React
(with the react-hook-form
library) form
import React, { useRef } from "react";
import { useForm } from "react-hook-form";
export default function App() {
const { register, handleSubmit, formState: { errors } } = useForm();
const firstNameRef1 = useRef(null);
const onSubmit = data => {
console.log("...onSubmit")
};
const { ref, ...rest } = register('firstName', {
required: " is required!",
minLength: {
value: 5,
message: "min length is <5"
}
});
return (
<form onSubmit={handleSubmit(onSubmit)}>
<hr/>
<input {...rest} name="firstName" ref={(e) => {
console.log("...ref")
ref(e)
firstNameRef1.current = e // you can still assign to ref
}} />
{errors.firstName && <span>This field is required!</span>}
<button>Submit</button>
</form>
);
}
I'm getting:
...ref
...ref
...onSubmit
...ref
...ref
in the console output after the Submit button click.
My question is why is there so many ...ref
re-calls? Should't it just be the one and only ref
call at all?
P.S.
When I've removed the formState: { errors }
from the useForm
destructuring line above the problem disappears - I'm getting only one ...ref
in the console output as expected.
CodePudding user response:
It is happening because you are calling ref(e)
in your input
tag. That's why it is calling it repeatedly. Try removing if from the function
and then try again.
<input {...rest} name="firstName" ref={(e) => {
console.log("...ref")
ref(e) // <-- ****Remove this line of code*****
firstNameRef1.current = e // you can still assign to ref
}} />
CodePudding user response:
My question is why is there so many ...ref re-calls?
This is happening because every time you render, you are creating a new function and passing it into the ref. It may have the same text as the previous function, but it's a new function. React sees this, assumes something has changed, and so calls your new function with the element.
Most of the time, getting ref callbacks on every render makes little difference. Ref callbacks tend to be pretty light-weight, just assigning to a variable. So unless it's causing you problems, i'd just leave it. But if you do need to reduce the callbacks, you can use a memoized function:
const example = useCallback((e) => {
console.log("...ref")
ref(e);
firstNameRef1.current = e
}, [])
// ...
<input {...rest} name="firstName" ref={example} />