I have an issue while selecting the object as value for Select component (Ant Design).
This is what I'm trying to do
import React, { useEffect, useState } from "react";
//Other imports
export const NewInvoice = () => {
const [selectedCustomer, setSelectedCustomer] = useState(null);
const [customers, setCustomers] = useState([]);
// other fields
useEffect(() => {
if (checkAuthentication(getToken())) {
fetchCustomers().then((data) => {
setCustomers(data);
});
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const customerNameHelper = (customer) => {
return `${customer?.customerNumber ?? ""} - ${customer?.name ?? "Unkown"}, ${customer?.addressDto?.city ?? "Unknown"}`;
};
const getCustomerAsOptions = (customers) => {
return customers.map((item) => ({
label: customerNameHelper(item),
value: item, // item = {id, name, customerNumber, ...}
}));
};
return (
// other components
{customers.length > 0 && (
<Select
style={{
width: 380,
}}
className="customerSelectionDropdown"
value={customerNameHelper(selectedCustomer)}
onChange={(value) => {
setSelectedCustomer(value);
}}
placeholder="Select Customer"
options={getCustomerAsOptions(customers)}
dropdownStyle={dropDownStyles}
showSearch
allowClear
/>
)}
);
};
Whenever I try to select the option it is saying Objects are not valid as a React child (found: object with keys {id, name, customerNumber, email, phone, pendingAmount, createdDate, addressDto, totalPurchaseAmount}). If you meant to render a collection of children, use an array instead.
Is there any solution to address this issue? Thank you in advance for your assistance.
You are sending an object
to property value
in getCustomerAsOptions
const getCustomerAsOptions = (customers) => {
return customers.map((item) => ({
label: customerNameHelper(item),
// CHANGE
value: item.customerNumber, // item = {id, name, customerNumber, ...}
}));
};
Type of the Option
in antd
is string | number | null
:
label: React.ReactNode;
value?: string | number | null;
You have to pass only string
| number
| null
and you are passing an object which throws error.
IMO: You should pass
unique
identifier so that on selecting a value from dropdown you can identify which element has been clicked. On click of an option it will return samevalue
to you inonChange
callback
onChange={(value) => {
setSelectedCustomer(value);
}}
MODIFICATION
: If you want to tract the object then you can create state and set it in onChange
callback as:
onChange={(value) => {
const selectedCust = customers.find(
(o) => o.customerNumber === value,
);
if (selectedCust) setSelectedCustomer(selectedCust);
}}
MODIDFICATION 2
: If you want to set the selected object then you can use second args to onChange
as:
onChange={(value, selectedCust) => {
setSelectedCustomer(selectedCust);
}}