i'm creating a SPA using React and noticed that in the creation of my navbar there is going to be a lot of repetition. What i want is six components like this:
function Navbar() {
return (
<nav className="navbar">
<div className="navbar-items">
<Logo />
<NavbarItem1 />
<NavbarItem2 />
<NavbarItem3 />
<NavbarItem4 />
<NavbarItem5 />
</div>
</nav>
)
}
Now for the repetition part, every component is going to be basically this:
function NavbarItem1() {
return (
<div className="navbar-item">
<button className="navbar-button">
<svg class="navbar-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 80" x="0px" y="0px">
<g>
<path
d="M52,7a5.006,5.006,0,0,0-5-5H7A5.006,5.006,0,0,0,2,7V56H4V7A3,3,0,1,1,8,9.816V7H6V62H48V11.9A5.009,5.009,0,0,0,52,7ZM8,60V12H46V60ZM47,10H10.974a4.9,4.9,0,0,0,0-6H47a3,3,0,0,1,0,6Z" />
<path
d="M57,8a5.006,5.006,0,0,0-5,5V52.236l5,10,5-10V13A5.006,5.006,0,0,0,57,8ZM56,48.586,54.845,47.43,54,48.7V22h2Zm-1.846,3.486,1-1.5L57,52.414l1.845-1.844,1,1.5L57,57.764ZM60,48.7l-.845-1.267L58,48.586V22h2ZM60,20H54V18h6Zm-6-4V13a3,3,0,0,1,6,0v3Z" />
<rect x="12" y="20" width="30" height="2" />
<rect x="12" y="28" width="30" height="2" />
<rect x="12" y="35" width="30" height="2" />
<rect x="12" y="43" width="30" height="2" />
<rect x="12" y="50" width="18" height="2" />
<rect x="36" y="50" width="2" height="2" />
<rect x="32" y="50" width="2" height="2" />
<rect x="40" y="50" width="2" height="2" />
</g>
</svg>
<span class="navbar-text">Item 1</span>
</button>
</div>
)
}
So instead of creating six components who are basically the same, is there a less repetitive way of doing this or is this the normal way people create navbars using React?? Thanks in advance for your answer.
Assuming that the parts that differ between each navbar item are the icon and its text content, you can extract the icons into their own components, then just pass the icon component and the text via props:
// Pass className via props so the NavbarItem can set it
function NoteIcon({ className }) {
return (
<svg
className={className}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 64 80"
x="0px"
y="0px"
>
<g>
<path d="M52,7a5.006,5.006,0,0,0-5-5H7A5.006,5.006,0,0,0,2,7V56H4V7A3,3,0,1,1,8,9.816V7H6V62H48V11.9A5.009,5.009,0,0,0,52,7ZM8,60V12H46V60ZM47,10H10.974a4.9,4.9,0,0,0,0-6H47a3,3,0,0,1,0,6Z" />
<path d="M57,8a5.006,5.006,0,0,0-5,5V52.236l5,10,5-10V13A5.006,5.006,0,0,0,57,8ZM56,48.586,54.845,47.43,54,48.7V22h2Zm-1.846,3.486,1-1.5L57,52.414l1.845-1.844,1,1.5L57,57.764ZM60,48.7l-.845-1.267L58,48.586V22h2ZM60,20H54V18h6Zm-6-4V13a3,3,0,0,1,6,0v3Z" />
<rect x="12" y="20" width="30" height="2" />
<rect x="12" y="28" width="30" height="2" />
<rect x="12" y="35" width="30" height="2" />
<rect x="12" y="43" width="30" height="2" />
<rect x="12" y="50" width="18" height="2" />
<rect x="36" y="50" width="2" height="2" />
<rect x="32" y="50" width="2" height="2" />
<rect x="40" y="50" width="2" height="2" />
</g>
</svg>
);
}
function NavbarItem({ icon: Icon, children }) {
return (
<div className="navbar-item">
<button className="navbar-button">
<Icon className="navbar-icon" />
<span className="navbar-text">{children}</span>
</button>
</div>
);
}
function Navbar() {
return (
<nav className="navbar">
<div className="navbar-items">
<Logo />
{/* Pass the correct icon component, and the text via children */}
<NavbarItem icon={NoteIcon}>Item 1</NavbarItem>
<NavbarItem icon={OtherIcon}>Item 2</NavbarItem>
<NavbarItem icon={AnotherIcon}>Item 3</NavbarItem>
</div>
</nav>
);
}