I want to display many icons on the same page but I understand looping through the same array many times each render is too much work and it will reduce performance especially in slower devices. How do you approach this problem?
The allIconsSet
array is stored and exported in a file and bundled in the app.
The services
array comes from a server so it can’t have React Components but only strings.
export const allIconsSet = [ { id: `live-sports`, icon: <FaTV/> }, { id: `drinking`, icon: <FaBeer/> }, { id: `smoking`, icon: <FaCigarette/> }, { id: `billiard`, icon: <FaBilliard/> }, // ... 500 more records ] const services = [ { title: `Live Sports`, slug: `live-sports` }, { title: `Drink`, slug: `drinking` }, { title: `Smoke`, slug: `smoking` }, { title: `Billiard`, slug: `billiard` }, // ... 100 more records ] function Services() { return ( <div className="Services"> { services.map( service => { const { title, slug } = service const icon = allIconsSet.map( item => { if ( slug === item.id ) return item.icon }); return ( <div className="service"> <div className="label">{ title }</div> <div className="icon">{ icon }</div> </div> ) }) } </div> ) } export default Services
Advertisement
Answer
Simply transform your icon Array
into an Object
. And you’ll be able to find an icon like this: allIconsSet['smoking']
.
const allIconsSet = { 'live-sports': { icon: <FaTV/> }, 'drinking': { icon: <FaBeer/> }, 'smoking': { icon: <FaCigarette/> }, 'billiard': { icon: <FaBilliard/> }, // ... }; const smokingIcon = allIconsSet.smoking; const liveSportsIcon = allIconSet['live-sports'];
If you don’t plan to add additional data, you could ditch the icon
field and directly pass the component as the icon property value, like: 'smoking': <FaCigarette />,
.
NOTE: Icons exists as webfonts that can be used just like any fonts making them easy to use, customizable with CSS and lightweight. Font Awesome does this, you should check it out, it will certainly be less memory/CPU intensive than having one component per icon.
EDIT: Below you’ll find an example of webfont usage with Google Material Icons.
/* You can replace all of this by putting this in your page <head> tag: <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> */ /* fallback */ @font-face { font-family: 'Material Icons'; font-style: normal; font-weight: 400; src: url(https://fonts.gstatic.com/s/materialicons/v85/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2) format('woff2'); } .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; font-size: 24px; line-height: 1; letter-spacing: normal; text-transform: none; display: inline-block; white-space: nowrap; word-wrap: normal; direction: ltr; -webkit-font-feature-settings: 'liga'; -webkit-font-smoothing: antialiased; } /* You can then stylized your icon just like any text */ .my-class { color: #333; font-size: 40px; }
<span class="my-class material-icons">delete</span> <span class="my-class material-icons">edit</span> <span class="my-class material-icons">alarm</span>