Reputation: 303
I have a sidebar components whose list items are generated inside of a map function (movie genres fetched from an api). I would like to have a different icon next to each of the movie genres but have been unable to figure out a way to create a different for each run of the map function.
My thoughts are 1st: make an array of the icons I would like to display, in the order that I would like them to display in.
const icons = [
"AiOutlineHome ",
"FaUserNinja",
"GiSwordman",
"GiBabyFace",
"FaLaughBeam",
"GiPistolGun",
"GiPineTree",
"GiDramaMasks",
"GiFamilyHouse",
"GiElfEar",
"GiScrollUnfurled",
"GiScreaming",
"GiMusicalNotes",
"GiMagnifyingGlass",
"FaRegKissBeam",
"GiMaterialsScience",
"GiHalfDead",
"GiGreatWarTank",
"GiCowboyBoot",
];
Then in my map function generate a different icon for each list item
{movieGenres.map((genre) => {
return (
<li key={genre.id} className="nav-text">
<button
className="genre-btn"
onClick={() => genreSelectionHandler(genre.id)}
>
*<GENERATE ICON HERE />*
<span className="nav-item-title">{genre.name}</span>
</button>
</li>
);
})}
Is it possible to pragmatically create components like this? So that I can avoid creating each list item individually if I want different icon.
Upvotes: 3
Views: 11789
Reputation: 16309
You can just take the index of your genre to get the icon. The index is the second argument to the callback of your map()
function:
{movieGenres.map((genre, idx) => (
<li key={genre.id} className="nav-text">
<button
className="genre-btn"
onClick={() => genreSelectionHandler(genre.id)}
>
<Icon icon={icons[idx]} />
<span className="nav-item-title">{genre.name}</span>
</button>
</li>
))}
The Icon
component would render the icon depending on what kind of icons you are using.
EDIT:
As you want to use react-icons
you need to import the actual icon components rather than just using strings:
import {AiOutlineHome} from "react-icons/ai";
import {FaUserNinja} from "react-icons/fa";
// ....
const icons = [
AiOutlineHome,
FaUserNinja,
// ...
];
And render them:
{movieGenres.map((genre, idx) => {
// must be a capitalized name in order for react to treat it as a component
const Icon = icons[idx];
return (
<li key={genre.id} className="nav-text">
<button
className="genre-btn"
onClick={() => genreSelectionHandler(genre.id)}
>
<Icon />
<span className="nav-item-title">{genre.name}</span>
</button>
</li>
)
})}
Upvotes: 8