Reputation: 809
How do I set a custom tag in React?
Each import is a JSX Element. For example, GitHub is imported from a file that looks like this:
import React from 'react';
const GitHub = () => (
<svg role="img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" height="1.5rem" width="1.5rem">
<title>GitHub Icon</title>
<path d="M171.25 408.36c0 2.06-2.37 3.7-5.37 3.7-3.4.32-5.78-1.33-5.78-3.7 0-2.07 2.38-3.72 5.37-3.72 3.1-.31 5.78 1.36 5.78 3.72zm-32.1-4.65c-.72 2.07 1.34 4.44 4.44 5.06 2.68 1 5.78 0 6.4-2.06.62-2.06-1.34-4.44-4.44-5.37-2.69-.72-5.68.3-6.4 2.37zm45.62-1.71c-3 .72-5 2.68-4.74 5.06.31 2.06 3 3.4 6.09 2.68 3.09-.72 5-2.68 4.74-4.75-.26-2.07-3.09-3.34-6.09-3zM252.7 6.4C109.52 6.4 0 115.09 0 258.27c0 114.47 72.05 212.44 175 246.9 13.21 2.39 17.86-5.77 17.86-12.48 0-6.4-.31-41.7-.31-63.38 0 0-72.26 15.49-87.44-30.76 0 0-11.76-30-28.69-37.78 0 0-23.64-16.21 1.65-15.9 0 0 25.7 2.07 39.84 26.64 22.61 39.84 60.49 28.38 75.26 21.57 2.37-16.52 9.08-28 16.51-34.8-57.68-6.4-115.95-14.75-115.95-114.05 0-28.4 7.84-42.63 24.36-60.8-2.68-6.71-11.46-34.38 2.68-70.1 21.58-6.7 71.23 27.88 71.23 27.88a242.6 242.6 0 0164.83-8.78 242.52 242.52 0 0164.82 8.78s49.65-34.68 71.23-27.87c14.14 35.82 5.37 63.38 2.68 70.09 16.52 18.27 26.63 32.5 26.63 60.8 0 99.6-60.8 107.56-118.5 114.06 9.5 8.16 17.55 23.64 17.55 47.9 0 34.79-.31 77.83-.31 86.3 0 6.7 4.75 14.86 17.86 12.49C442 470.7 512 372.74 512 258.27 512 115.09 395.87 6.4 252.7 6.4zm-152.36 356c-1.35 1-1 3.4.72 5.37 1.65 1.65 4 2.37 5.37 1 1.34-1 1-3.4-.73-5.37-1.65-1.6-4.02-2.32-5.36-.98zm-11.15-8.36c-.73 1.34.31 3 2.37 4 1.65 1 3.72.72 4.44-.73.72-1.45-.31-3-2.37-4-2.07-.6-3.72-.31-4.44.75zm33.44 36.75c-1.65 1.34-1 4.44 1.34 6.4 2.38 2.37 5.37 2.68 6.71 1 1.35-1.34.73-4.44-1.34-6.4-2.27-2.32-5.34-2.63-6.71-.98zm-11.77-15.18c-1.65 1-1.65 3.72 0 6.1 1.65 2.38 4.44 3.4 5.79 2.37 1.65-1.34 1.65-4 0-6.4-1.45-2.37-4.13-3.41-5.79-2.07z"/>
</svg>
);
export default GitHub;
The other icons are imported from their respective files in the same format. I now want to loop through DATA
to render each icon.
import React, { Component } from 'react';
import GitHub from './../assets/GitHub'
import LinkedIn from './../assets/LinkedIn'
import Email from './../assets/Email'
const DATA = [
{
href: "...",
aria: "...",
icon: GitHub,
label: "...",
},
{
href: "...",
aria: "...",
icon: LinkedIn,
label: "...",
},
{
href: "...",
aria: "...",
icon: Email,
label: "...",
}
];
const Button = ({ href, aria, icon, label }) => {
return (
<span className="button-container">
<a className="button" href={href} target="_self" aria-label={aria} rel="noopener noreferrer">
<{icon} className="icon"/>
<span className="icon_title">{label}</span>
</a>
</span>
);
};
class Buttons extends Component {
render() {
return (
<div>
{DATA.map((props, i) => (
<Button {...props} key={i} />
))}
</div>
);
}
}
export default Buttons;
The line of code is where I am having difficulty is <{icon} className="icon"/>
. I do not know how to set a custom HTML tag while looping
Also, any other feedback would be appreciated. In DATA
, should I store each icon as an alias to the import or should I instead have icon: "GitHub"
?
Thanks!
Upvotes: 1
Views: 279
Reputation: 1
Since React exige capitalized component names, you could assign that prop to a local variable called Icon
then use render it as JSX :
const Button = ({ href, aria, icon, label }) => {
let Icon=icon;
return (
<span className="button-container">
<a className="button" href={href} target="_self" aria-label={aria} rel="noopener noreferrer">
<Icon className="icon"/>
<span className="icon_title">{label}</span>
</a>
</span>
);
};
or set the icons as elements in the DATA array like :
const DATA = [
{
href: "...",
aria: "...",
icon: <GitHub className="icon" />,
label: "...",
},
...
then render it as follows :
const Button = ({ href, aria, icon, label }) => {
return (
<span className="button-container">
<a className="button" href={href} target="_self" aria-label={aria} rel="noopener noreferrer">
{icon}
<span className="icon_title">{label}</span>
</a>
</span>
);
};
Please check this example
Upvotes: 2
Reputation: 84957
You'll need to rename it to Icon
with a capital I
(this convention distinguishes custom components from built in ones like <div>
), but other than that you use it just like you would any other component:
const Button = ({ href, aria, icon: Icon, label }) => {
return (
<span className="button-container">
<a className="button" href={href} target="_self" aria-label={aria} rel="noopener noreferrer">
<Icon className="icon"/>
<span className="icon_title">{label}</span>
</a>
</span>
);
};
Upvotes: 3