I have a list of categories coming form an API call:
Diagnosis
Client Statements
Damages
I need to assign an icon on the frontend to each of the categories received and I thought the best way to do this was to map the categories using a switch
statement.
let icon = '';
const handleIcon = () => {
categories.map((cat) => {
switch (cat.categoryName) {
case 'Diagnosis':
icon = 'checklist-24';
break;
case 'Client Statements':
icon = 'document-24';
break;
case 'Damages':
icon = 'car-crash-24'
break;
default:
break;
}
});
};
My problem is that all the categories end up being the last icon because they are all true in the end for my map function.
categories.map((cat) => {
<div>{icon}</div>
<div>{cat.categoryName}</div>
})
How can I assign a different icon according to the name of the category in my map?
Thanks.
CodePudding user response:
This is the right way to handle this kind of scenarios, which is, when you have to do extra manipulations on your data before displaying them:
const cats = [
{ categoryName: 'Diagnosis' },
{ categoryName: 'Client Statements' },
{ categoryName: 'Damages' },
];
export default function App() {
const [categories, setCategories] = useState(cats);
const _categories = useMemo(() => {
return categories.map((cat) => ({
...cat,
icon: getIcon(cat.categoryName),
}));
}, [categories]);
return (
<div>
{_categories.map((cat) => (
<div>
{cat.categoryName}:{cat.icon}
</div>
))}
</div>
);
}
function getIcon(name) {
switch (name) {
case 'Diagnosis':
return 'checklist-24';
case 'Client Statements':
return 'document-24';
case 'Damages':
return 'car-crash-24';
default:
return '';
}
}
In this way you are memoizing your manipulation which is anyway expensive and you don't want it to happen on each rerender if categories don't change, and you use a pure function getIcon() to attach the relative icon to your category object. You can attach whatever you want, even a JSX Component to be displayed directly.
Test it HERE