Description: I'm a novice at reactJS and Javascript in general. I'm creating a component whereby I'm grabbing 5 social media icons (Facebook, Instagram, LinkedIn, Twitter, Github) and creating a simple component whereby they become clickable buttons that are sourced to my social media sites.
I'm capable of it, however I'm certain there is a much more concise way of creating this component, I'm just not knowledgable of how to do so.
Question What is the most efficient way creating this component?
For example, can I reduce the amount importing calls as well as button tag creations?
Code
import {BsTwitter} from "react-icons/bs"
import {FaFacebookF} from "react-icons/fa"
import {FaInstagram} from "react-icons/fa"
import {FaLinkedinIn} from "react-icons/fa"
import {BsGithub} from "react-icons/bs"
export default function Icons(){
return(
<div className = "icons">
<button>
<BsTwitter/>
</button>
<button>
<FaFacebookF/>
</button>
<button>
<FaInstagram/>
</button>
<button>
<FaLinkedinIn/>
</button>
<button>
<BsGithub/>
</button>
</div>
)
}
I tried creating an array and using the spread operator, however, I think I'm clearly doing somethign wrong.
CodePudding user response:
This looks good as is, but if you have a lot of these icons, you can clean it up by dynamically lazy loading them. Bear in mind this increases the complexity. Additionally, you'll still need to have a map of the icon names and the path to the exported module (since they can be from different modules)
codesandbox: https://codesandbox.io/s/musing-cartwright-5vgt3k?file=/src/App.js, but will paste below as well:
import "./styles.css";
import { lazy, Suspense } from "react";
const icons = [
{ BsTwitter: "bs" },
{ FaFacebookF: "fa" },
{ FaInstagram: "fa" }
];
const components = icons.map((icon) => {
const { 0: name, 1: path } = Object.entries(icon)[0];
// react.lazy only imports default export, so let's remap the default
return lazy(() =>
import(`react-icons/${path}`).then((module) => ({ default: module[name] }))
);
});
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Suspense fallback={<div>Loading...</div>}></Suspense>
<div className="icons">
{components.map((Component) => (
<button>
<Component />
</button>
))}
</div>
</div>
);
}
[1]: https://codesandbox.io/s/musing-cartwright-5vgt3k?file=/src/App.js
CodePudding user response:
You could create a ButtonList component. This will save you time if you ever need to change what wraps the icons. Here is a code sandbox https://codesandbox.io/s/angry-platform-7zn7rq?file=/src/App.js
export default function ButtonList({ children }) {
return (
<div className="App">
{React.Children.map(children, (child, i) => {
return <button>{React.cloneElement(child)}</button>;
})}
</div>
);
}
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<ButtonList>
<BsTwitter />
<FaFacebookF />
<FaInstagram />
<BsGithub />
<FaLinkedinIn />
</ButtonList>
</div>
);
}
This will map over the children (your icons) and render each of them as a button.