Reputation: 103
react-hook-form works just fine. the problem is when I wanted to attach an onBlur callback on the input field. The onFocus works just fine, but when I take the focus to other input fields or anywhere else, the onBlur event is not fired.
When I removed the register feature from react-hook-form onBlur works just fine, but is not fired when I use register from react-hook-form.
...
"react-hook-form": "^7.41.1",
"react": "^18.2.0"
...
here is the first component in the form
< div className="pb-5">
< label
className="block text-sm font-medium mb-1"
htmlFor="name">
Name <span className="text-rose-500">*</span>
< /label>
<input
id="name"
className="form-input w-full ml-2 "
type="text"
defaultValue={projectState.project.app.name ?? '-'}
name="name"
onFocus={() => {
console.log('got focus')
}}
onBlur={(event) => {
console.log('lost focus')
}}
{...register('name', {
required: {value: true, message: "Name is required"},
},
)}
/>
{errors.name && <p className={`ml-2 mt-1 text-red-600`}>
<span>{errors.name.message}</span>
</p>}
</div>
I tried to attach a callback to an onBlur event. The event is fired when not using react-hook-form. The onBlur event is not being fired when I am using react-hook-form, only the onFocus is fired
Upvotes: 5
Views: 1179
Reputation: 91
This is how I handled mine using a custom react component.
const onBlurHandler = (e) => {
const inputHighlight = e.target;
inputHighlight.style.backgroundColor = "#ff40401a";
inputHighlight.style.borderWidth = "1px";
inputHighlight.style.borderColor = "#ff4040";
};
My custom input react component:
<form onSubmit={handleSubmit(onSubmit)}>
<div className="mb-6">
<ContactInputBox
type="text"
name="name"
id="name"
placeholder="Your Name"
onChange={handleChange}
register={register}
validationRules={{
required: "You must enter your name",
maxLength: {
value: 200,
message: "Name must be less than 200 characters",
},
onBlur: onBlurHandler // my handler function
}}
/>
{errors.name && (
<div className="text-red-500">{errors.name.message}</div>
)}
</div>
<div className="mb-6">
<ContactInputBox
type="email"
name="email"
id="email"
placeholder="Your Email"
onChange={handleChange}
register={register}
validationRules={{
required: "You must enter a valid email",
pattern: {
value:
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
message: "You must enter a valid email",
},
maxLength: {
value: 128,
message: "Email must be less than 128 characters",
},
onBlur: onBlurHandler
}}
/>
{errors.email && (
<div className="text-red-500">{errors.email.message}</div>
)}
</div>
</form>
And inside the custom component, I do this:
import React from "react";
const ContactInputBox = ({
type,
placeholder,
name,
id,
register,
validationRules
}) => (
<>
<label
htmlFor={id}
className="mb-[10px] block capitalize text-base font-medium text-black"
>
{name}
</label>
<div className="relative">
<input
id={id}
type={type}
placeholder={placeholder}
name={name}
className="w-full bg-[#efe5dc] rounded-md border border-stroke border-black px-[14px] py-3 text-body-color outline-none"
{...register(name, validationRules)}
/>
</div>
</>
);
// Adding a displayName to the component
ContactInputBox.displayName = "ContactInputBox";
export default ContactInputBox;
This works as expected. The onBlur
effect will now take effect.
Upvotes: 1
Reputation: 4946
register
function overrides value
, name
, onChange
, and onBlur
props
To add logic to onBlur:
const {onBlur, ...fieldProps} = register('name', {
required: {value: true, message: "Name is required"},
})
return (
// ...
<input
id="name"
className="form-input w-full ml-2 "
type="text"
onFocus={() => {
console.log('got focus')
}}
onBlur={(event) => {
console.log('lost focus')
onBlur()
}}
{...fieldProps}
/>
// ...
)
Upvotes: 5