显示一个基于作为字符串传递的道具的图标-React



我正试图根据一个道具(来自每个用户存储在数据库中的字符串(显示不同的图标。我不想将图标本身作为道具传递,因为关于要显示的图标的信息存储在数据库中。

我的父组件获取数据并获得一个我称之为";displayIcon";作为字符串。这被作为道具传递给";AppCard";根据displayIcon的值,我想渲染不同的图标。

一种方法是使用三元运算符,但它感觉不太可扩展、优雅或高效。

有什么建议吗?

我如何传递数据:

return (
<BaseLayout title={"Processes"}>
{userRole == "stakeholder" && (
<AppSection sectionName={"Add Processes"}>
<div className="appLayout">
<AppCard
title={"Add process"}
navigation={"/processes/addnew"}
displayIcon={"FaPlus"}
/>
</div>
</AppSection>
)}
);

AppCard组件

// import { FaQuestion } from "react-icons/fa";
import Link from "next/link";
import {
FaPlus,
FaSitemap,
FaQuestion,
FaRegListAlt,
FaUser,
} from "react-icons/fa";
import {
HiOutlineUserGroup,
HiCog,
HiDocumentText,
HiOutlineFire,
HiAcademicCap,
HiLightBulb,
HiScale,
HiOutlineChartPie,
HiOutlineFlag,
HiOutlineGlobe,
} from "react-icons/hi";
function AppCard({title, navigation, displayIcon }) {
return (
<Link
href={{
// pathname: `/admin/edit/${navigation}`,
pathname: navigation,
}}
>
<div className=" cursor-pointer flex flex-col items-center ">
<div className="appView ">

{displayIcon == "FaPlus" && <FaPlus size="44" />}
{displayIcon == "FaUser" && <FaUser size="44" />}
{displayIcon == "FaSitemap" && <FaSitemap size="44" />}
{displayIcon == "FaQuestion" && <FaQuestion size="44" />}
{displayIcon == "FaRegListAlt" && <FaRegListAlt size="44" />}
{displayIcon == "HiOutlineUserGroup" && (
<HiOutlineUserGroup size="44" />
)}
{displayIcon == "HiCog" && <HiCog size="44" />}
{displayIcon == "HiDocumentText" && <HiDocumentText size="44" />}
{displayIcon == "HiOutlineFire" && <HiOutlineFire size="44" />}
{displayIcon == "HiAcademicCap" && <HiAcademicCap size="44" />}
{displayIcon == "HiLightBulb" && <HiLightBulb size="44" />}
{displayIcon == "HiScale" && <HiScale size="44" />}
{displayIcon == "HiOutlineChartPie" && (
<HiOutlineChartPie size="44" />
)}
{displayIcon == "HiOutlineFlag" && <HiOutlineFlag size="44" />}
{displayIcon == "HiOutlineGlobe" && <HiOutlineGlobe size="44" />}

</div>
<p className="text-siteTheme-accentcolorDark font-psans  mt-1">
{title}
</p>
</div>
</Link>
);
}
export default AppCard;

我在我的个人网站上为社交档案组件做你所描述的。我实现它的方式是:

  1. 将我将支持的所有Font Awesome图标导入到组件中我相信这在未来可以优化,但我还没有探索过

import {
faStackOverflow,
faTwitter
} from '@fortawesome/free-brands-svg-icons'

  1. 根据这些创建受支持的icons的注册表

const icons = {
faStackOverflow,
faTwitter
}

  1. 获取我的社交档案数据。在它中,我定义了图标,按键,我想用于每个配置文件。这些键当前对应于导入名称(,例如"faStackOverflow">(

const profiles = useSocialProfiles()
/*
[{
"icon": {
"name": "stack-overflow",
"reactIcon": "faStackOverflow"
},
"displayName": "StackOverflow"
}, {
"icon": {
"name": "twitter",
"reactIcon": "faTwitter"
},
"displayName": "Twitter"
}]
*/

  1. 循环浏览所有配置文件,并使用支持的图标注册表将每个图标键映射到新的IconComponent字段。它包含图标SVG

const profilesToIcons = profile => {
const { icon: { reactIcon } = {} } = profile
return {
IconComponent: icons[reactIcon],
profile
}

const profilesWithIcons = profiles.map(profilesToIcons)

  1. 渲染配置文件,将每个IconComponentreact-fontawesome传递到<FontAwesomeIcon />

{profilesWithIcons.map(({ IconComponent }) => (
<FontAwesomeIcon
icon={IconComponent}
sx={{ fontSize: [4, 5, 6] }}
/>
))}

我的配置文件数据源以前是一个数据库,但现在我使用一个配置文件。同样的实现对两者都起到了良好的作用。如果您注意到图标的数量(已使用或未使用(增加了客户端的捆绑包大小,超过了可接受的范围,那么您可能需要对此进行重构或迭代以解决此问题。可能有几种方法可以解决这个问题,但我还没有亲自到达那里。目前,这已经很好地满足了我的需求和我正在导入的几个图标。

您可以将所有内容存储在一个对象中,并根据需要进行渲染。

const STRING_TO_ICON = {
FaPlus: <FaPlus size="44" />,
FaUser: <FaUser size="44" />},
FaSitemap: <FaSitemap size="44" />,
FaRegListAlt: (size = 44) => <FaRegListAlt size={size} /> // dynamic size
}
function AppCard({ title, navigation, displayIcon }){
...
return(
...
<div className="appView ">
{STRING_TO_ICON[displayIcon]}
{STRING_TO_ICON[displayIcon(32)]}
</div>
...
);
...
}

最新更新