My question may sound confusing, and frankly it does. What I am attempting to make is a component to use later on multiple different locations. The component is a card with an icon, some text and a button. What I have in the dictionary are all possible icons I will be using for this project. What I don't have is the knowledge of how to do this. I am trying to implement the "DRY" principal, hence why I seek to do it this way. I would like a card which can be imported then have some variables that will add the icon, text and button.
Here is my code below.
import React from "react";
import Button from "../Button/Button";
import { IoAppsSharp } from "react-icons/io5";
import { ImDisplay } from "react-icons/im";
import { AiFillSignal } from "react-icons/ai";
import { MdPhoneInTalk } from "react-icons/md";
import { GrCode } from "react-icons/gr";
import { MdSecurity } from "react-icons/md";
import { IoMdSchool } from "react-icons/io";
const iconDict = {
iconOne: <IoAppsSharp />,
iconTwo: <ImDisplay />,
iconThree: <AiFillSignal />,
iconFour: <MdPhoneInTalk />,
iconFive: <GrCode />,
iconSix: <MdSecurity />,
iconSeven: <IoMdSchool />
}
const Card = ({ icon, title, text, button }) => {
const checkIcon = iconDict.includes(icon) ? icon : iconDict.iconOne;
return (
<a
href="Bespoke Software"
className="card"
>
<div className="card__icon-container">
<IoAppsSharp className="card__icon-container--icon" />
</div>
<div className="card__text-container">
<h2>Bespoke Software</h2>
<p>
Tailored software solutions to improve business productivity and
online profits.
</p>
<br />
</div>
<div className="card__button-container">
<Button>Read More</Button>
</div>
</a>
);
}
export default Card;
CodePudding user response:
Re your title:
How Does One Replace an Import with a variable?
You can't parameterize modules like that, but the good news is you don't have to to solve your problem. :-)
Instead, we can solve it like this: Make Card
, itself, directly accept the icon, not the name of the icon, and then (optionally) use a Higher-Order Component (HOC) to create a version of Card
that accepts names instead (using a given dictionary).
The new Card
:
import React from "react";
import Button from "../Button/Button";
const Card = ({ checkIcon, title, text, button }) => {
return (
<a href="Bespoke Software" className="card">
<div className="card__icon-container">
<IoAppsSharp className="card__icon-container--icon" />
</div>
<div className="card__text-container">
<h2>Bespoke Software</h2>
<p>
Tailored software solutions to improve business productivity and online profits.
</p>
<br />
</div>
<div className="card__button-container">
<Button>Read More</Button>
</div>
</a>
);
};
Using Card
directly:
<Card checkIcon={<IoAppsSharp/>} {/*...*/} />
// Or keep using `iconDict`:
<Card checkIcon={iconDict.iconOne} {/*...*/} />
The optional HOC:
function withIcons(Card, iconDict) {
return ({icon, ...rest}) => {
const checkIcon = iconDict.includes(icon) ? icon : iconDict.default; // Note I changed the name of the default
return <Card checkIcon={checkIcon} {...rest} />;
};
}
Using the HOC:
const iconDict = {
iconOne: <IoAppsSharp />,
iconTwo: <ImDisplay />,
iconThree: <AiFillSignal />,
iconFour: <MdPhoneInTalk />,
iconFive: <GrCode />,
iconSix: <MdSecurity />,
iconSeven: <IoMdSchool />,
};
const CardWithCertainIcons = withIcons(Card, iconDict);
Using that component:
<CardWithCertainIcons icon="iconOne" {/*...*/ />
If doing the HOC, see the link earlier for some important information about them re refs and static methods and such.