Reputation: 394
I am using react-hook-form controller with react-select. I am using React with Typescript. I can get the value of selected when submit, but it returns the both value and label from options array as an object.How can I return value only? here is the code,
const { handleSubmit, control, formState:{errors}} = useForm<IAddProductForm>();
const handleOnSubmit = (data:IAddProductForm) => {
console.log(data);
}
const categoryOptions = [
{value:"Grocery", label:"Grocery"},
{value:"Pharmacy", label:"Pharmacy"},
{value:"Electronic", label:"Electronic"},
{value:"Food", label:"Food"},
];
return(
<React.Fragment>
<Form onSubmit={handleSubmit(handleOnSubmit)}>
<Controller
control={control}
render={({field:{onChange, value, name, ref}}) => (
<Select
inputRef={ref}
value={categoryOptions.find(c => c.value === value)}
options={categoryOptions}
onChange={onChange}
/>
)}
name={"category"}
/>
<Button type={"submit"}>submit</Button>
</Form>
</React.Fragment>
);
this code returns category: {value: "Grocery", label: "Grocery"}
this if I select Grocery and submit it. but I need to return category:"Grocery"
like this.
Upvotes: 2
Views: 14391
Reputation: 3505
Hey it is actually a matter of changing your on change function and to use the value like this:
interface IAddProductForm {
category: string;
}
interface ICategory {
value: string;
label: string;
}
function YourComp() {
const { handleSubmit, control, formState:{errors}} = useForm<IAddProductForm>();
const handleOnSubmit = (data:IAddProductForm) => {
console.log(data);
}
const categoryOptions: ICategory[] = [
{value:"Grocery", label:"Grocery"},
{value:"Pharmacy", label:"Pharmacy"},
{value:"Electronic", label:"Electronic"},
{value:"Food", label:"Food"},
];
return(
<React.Fragment>
<Form onSubmit={handleSubmit(handleOnSubmit)}>
<Controller
control={control}
render={({ field: { onChange, value, name, ref } }) => (
<Select
inputRef={ref}
value={categoryOptions.find((c) => c.value === value)}
name={name}
options={categoryOptions}
onChange={(selectedOption: ICategory) => {
onChange(selectedOption.value);
}}
/>
)}
name={"category"}
/>
<Button type={"submit"}>submit</Button>
</Form>
</React.Fragment>
);
}
If you take a look closely I just add some types for the categoryOptions const to be able to type the onChange function and modify it to look like this.
onChange={(selectedOption: ICategory) => {
onChange(selectedOption.value);
}}
Basically the value received is the full object and you just need to extract the value of it in and pass it to the controller onChange function. Also you're right by passing the value and using the array find to match the object and make the select work properly.
If you submit that you should be able to see that the formData returns a category with the string value only, not the object.
Here's a working sandbox: https://codesandbox.io/s/boring-blackwell-qoer1
Upvotes: 7