I cannot find a solution to make react-select and react-hook-form work.
I constantly get an error: Cannot read properties of undefined (reading 'name') and an error telling me that my field is required.
Here is my code in codesandbox: https://codesandbox.io/s/funny-elbakyan-h5xz8w?file=/src/App.tsx:0-1347
Below is my code:
// InputSelect.tsx
import React from "react";
import clsx from "clsx";
import { default as ReactSelect, MenuPlacement } from "react-select";
export type SelectOption = {
value: string;
label: string;
key?: string;
};
export type InputSelectProps = {
name: string;
onChange: (value: any) => void;
options: SelectOption[];
error?: string;
};
const InputSelect: React.FC<InputSelectProps> = React.forwardRef(
({ id, options, name, onChange, label = "", error }, ref: React.Ref<any>) => {
const prefix = React.useId();
const inputId = id ?? `${prefix}-${name}`;
const isError = Boolean(error);
const [
selectedOption,
setSelectedOption
] = React.useState<SelectOption | null>(null);
const handleChange = (event: any) => {
console.log(event);
setSelectedOption(event);
// BUG is here - Cannot read properties of undefined (reading 'name')
onChange(event);
};
return (
<div className={clsx("c-form-field")}>
<label
className={clsx("c-form-field__label c-label pb-2.5")}
htmlFor={inputId}
>
{label}
</label>
<ReactSelect
name={name}
options={options}
onChange={(selectedOption) => {
handleChange(selectedOption);
}}
value={selectedOption}
/>
{/* Error messages */}
{isError && <p className="text-danger">{error}</p>}
</div>
);
}
);
export default InputSelect;
// App.tsx
import React from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as Yup from "yup";
import InputSelect from "./InputSelect";
enum OrganizationRole {
ADMIN = "ADMIN",
MANAGER = "MANAGER",
USER = "USER"
}
interface FormData {
email: string;
role: string;
}
const options = Object.values(OrganizationRole).map((role) => ({
value: role,
label: role
}));
const App: React.FC = () => {
const {
handleSubmit,
register,
formState: { errors }
} = useForm<FormData>({
resolver: yupResolver(
Yup.object({
email: Yup.string().email("Invalid email address").required("Required"),
role: Yup.string().required("Required")
})
)
});
const onSubmit = (data: FormData) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<input type="email" {...register("email")} />
{errors.email && <p>Email est requis</p>}
</div>
<div>
<InputSelect
label={"Role"}
error={errors.role?.message}
options={options}
required
{...register("role")}
/>
{errors.role && <p>Rôle est requis</p>}
</div>
<button type="submit">Envoyer</button>
</form>
);
};
export default App;