Reputation: 2381
I'm trying to add react-hook-form
to my reactstrap
form and inputs, but looks like it has a conflict between the packages.
import React, { useState, useEffect } from 'react';
import { useForm } from "react-hook-form";
import {
Button,
Form,
Label,
Input
} from 'reactstrap';
import { FormControlLabel, Checkbox, FormGroup } from '@material-ui/core';
...
const { register, handleSubmit, errors } = useForm();
...
const updDetails = (data) => {
console.log(data);
}
return (
<Form onSubmit={handleSubmit(updDetails)}>
<FormGroup className="mr-10 mb-10">
<Label for="compName" className="mr-sm-10">Company Name</Label>
<Input type="text" name="compName" id="compName" placeholder="Company Name"
ref={register({ required: true })} aria-invalid={errors.name ? "true" : "false"}
value={compDetails.compName} onChange={(e) => setCompDetails({...compDetails, compName: e.target.value})}
/>
{errors.name && errors.name.type === "required" && (
<span role="alert">This is required</span>
)}
</FormGroup>
<Button type="submit" className="col-sm-3" color="primary">Update Details</Button>
</Form>
)
...
When I load the page, I can see in the browser console warnings for all my inputs: Field is missing `name` attribute
. However, I am adding the name to every input as in the code above. Also, when I click on Update Details
with an empty value for the compName
it submits and the data is empty object.
Can't I use react-hook-form
with reactstrap
?
Thanks
Upvotes: 2
Views: 3889
Reputation: 955
If you're trying to do this in 2023 and with Typescript, then you'll get a TS error when trying to assign a bunch of properties output by register(...)
to innerRef
that only expects one element of one of the 3 types, so you'll see something like this: Type 'UseFormRegisterReturn<"compName">' is not assignable to type 'Ref<HTMLInputElement | HTMLTextAreaElement> | undefined'
Replacing the ref
part of the register(...)
output with innerRef
solved it for me:
const {
register,
handleSubmit,
formState: { errors }
} = useForm();
const registerRs = (fieldName: string, options = {}) => {
const registeredField: Partial<UseFormRegisterReturn> = register(fieldName, options);
const ref = registeredField.ref;
delete registeredField.ref;
return {...registeredField, innerRef: ref};
}
...
<Input
type="text"
id="compName"
placeholder="Company Name"
{...registerRs("compName", { required: true })}
aria-invalid={errors.compName ? "true" : "false"}
/>
Upvotes: 1
Reputation: 7666
You probably have to use innerRef
instead of ref
on the Input
component. i found this in the source here.
<Input
type="text"
name="compName"
id="compName"
placeholder="Company Name"
innerRef={register({ required: true })}
aria-invalid={errors.compName ? "true" : "false"}
/>
Upvotes: 6
Reputation: 970
I am not familiar with the reactstrap
code, but a thing you could do is pass the name to the register function, use it this way:
ref={register({name: 'input-name', /* rest of options*/})}
Hope I could help :D
Upvotes: 1