问题描述
我在我的 React 应用程序中使用了 react-icons 包。它工作正常,您可以通过以下方式导入和使用字体真棒图标:
import { FaTag } from 'react-icons/fa';
...
<FaTag />
但是,我希望能够在更可重用的组件中生成这些图标。例如,支持我有一个菜单列表并且每个项目都有一个图标。该列表作为一个数组发送,其中一个条目是标题,一个是链接地址,一个是图标的名称。没有动态方法,你必须这样做......
const SidebarMenuItem:FC<propsObj> = ({title,link,icon}):ReactElement => {
return (
<li>
<Link to={link}>
<span>{title}</span>
{ (icon==="Tag") && <FaTag /> }
{ (icon==="QuestionCircle") && <FaQuestionCircle /> }
{ (icon==="UserAstrounaut") && <FaUserAstronaut /> }
{ (icon==="InfoCircle") && <FaInfoCircle /> }
{ (icon==="List") && <FaList /> }
{ (icon==="Cogs") && <FaCogs /> }
</Link>
</li>
)
}
export default SidebarMenuItem;
我希望能够在某种程度上动态地执行此操作。我对包含我需要使用的每个图标的大型导入语句没有任何问题。之后我想做的是......
const SidebarMenuItem:FC<propsObj> = ({title,icon}):ReactElement => {
const iconElement = React.createElement(icon,null);
return (
<li>
<Link to={link}>
<span>{title}</span>
<div>{iconElement}</div>
</Link>
</li>
)
}
export default SidebarMenuItem;
这实际上会导致渲染正确的组件。但是,没有图标出现,也没有带有 svg 图形。似乎在编译过程中的某个地方,font awesome 包会在运行创建组件之前渲染图形?
有什么办法可以解决这个问题吗?
解决方法
你可以制作一个像
这样的组件数组import React from 'react'
import { FaTag,FaList } from 'react-icons/fa'
const components = {
FaTag,FaList,}
function SidebarMenuItem({title,link,icon}) {
//given that icon contains 'Tag' or 'List'
const Icon = components[`Fa${icon}`]
return (
<li>
<Link to={link}>
<span>{title}</span>
<Icon />
</Link>
</li>
)
}
,
我猜你正在使用一个模块打包器,它智能地只包含你在代码中使用过的文件(比如 webpack)。有关详细信息,请参阅 tree shaking。
如果你只是想制作一个需要图标的组件,你可以简单地通过 props 注入它:
const SidebarMenuItem:FC<propsObj> = ({title,IconComponent}):ReactElement => {
return (
<li>
<Link to={link}>
<span>{title}</span>
<IconComponent />
</Link>
</li>
)
}
export default SidebarMenuItem;
// use this like so:
import { FaTag } from 'react-icons/fa';
//... somewhere in render
<SidebarMenuItem title="the title" link="http://google.com" icon={FaTag} />
这并没有去掉 import
语句,但是因为像 vscode 这样的 IDE 会在你编码时自动插入导入(如果配置正确),我认为这没什么大不了的。此外,它使您的模块打包器实际上只包含您使用的图标。