动态导入 React Material UI 图标
Posted
技术标签:
【中文标题】动态导入 React Material UI 图标【英文标题】:Import React Material UI Icons dynamically 【发布时间】:2021-03-22 18:05:27 【问题描述】:主要思想是仅在需要时导入 react material UI 图标,或者在编译时我们不知道图标名称的动态时导入。 (让我们保证我们会有有效的图标名称)。
我的方法是使用带有动态路径的 require 语句:
const IconComponent = require(`@material-ui/icons/$icon`).default;
这工作正常,但出现了一些警告。
./node_modules/@material-ui/icons/utils/createSvgIcon.d.ts 3:8 模块解析失败:意外令牌 (3:8) 您可能需要适当的加载程序来处理此文件类型。 |从“@material-ui/core/SvgIcon”导入 SvgIcon; | 声明函数 createSvgIcon(path: React.ReactNode, displayName: string): typeof SvgIcon; | |导出默认createSvgIcon;
./node_modules/@material-ui/icons/index.d.ts 4:5 模块解析失败:意外令牌 (4:5) 您可能需要适当的加载程序来处理此文件类型。 |从“@material-ui/core/SvgIcon”导入 SvgIcon; |
type SvgIconComponent = typeof SvgIcon; | |导出 const AccessAlarm: SvgIconComponent;
我的问题是:我们如何才能避免这些警告并以适当的方式进行动态导入?
【问题讨论】:
请提供一个可重现情况的 sn-p,以便我们将其用作起点。 【参考方案1】:首先是
(async () =>
if (somethingIsTrue)
const default: myDefault, foo, bar = await
import('/modules/my-module.js');
)();
第二种方法是
let module = await import('/modules/my-module.js');
你可以调整的很好的工作示例是
const main = document.querySelector("main");
for (const link of document.querySelectorAll("nav > a"))
link.addEventListener("click", e =>
e.preventDefault();
import('/modules/my-module.js')
.then(module =>
module.loadPageInto(main);
)
.catch(err =>
main.textContent = err.message;
);
【讨论】:
恐怕你没有抓住重点。我尝试导入的模块名称是动态的。我无法在编译时告诉模块。它是在运行时决定的。诀窍是如何在不引发错误或警告的情况下实现此行为,因为我让它工作但无法摆脱该警告。如果我遗漏了什么,请纠正我。【参考方案2】:您可以为此创建一个hook。像下面这样。
//1) $ npm i string-similarity
import * as icons from '@material-ui/icons'
import stringSimilarity from 'string-similarity'
function useIcons(word)
const iconsNames = Object.keys(icons)
var matches = stringSimilarity.findBestMatch(word, iconsNames)
const bestMathch = matches.bestMatch.target
const Icon = icons[bestMathch]
return Icon
export default useIcons
import Icon from './myCustomeHooks/useIcons'
// other file like
const Icon = useIcons('tablechart') // not the name should start with capital letter in case you use reactjs
// now you can use the icon as you like
<Icon/>
请注意:import * as icons from '@material-ui/icons'
与const * as icons = require('@material-ui/icons').default;
相同
option 2
import React from 'react';
import loadCSS from 'fg-loadcss';
import makeStyles, createStyles, Theme from '@material-ui/core/styles';
import green from '@material-ui/core/colors';
import Icon from '@material-ui/core/Icon';
const useStyles = makeStyles((theme: Theme) =>
createStyles(
root:
'& > .fa':
margin: theme.spacing(2),
,
,
),
);
export default function FontAwesome()
const classes = useStyles();
React.useEffect(() =>
const node = loadCSS(
'https://use.fontawesome.com/releases/v5.12.0/css/all.css',
document.querySelector('#font-awesome-css'),
);
return () =>
node.parentNode!.removeChild(node);
;
, []);
return (
<div className=classes.root>
<Icon className="fa fa-plus-circle" />
<Icon className="fa fa-plus-circle" color="primary" />
<Icon className="fa fa-plus-circle" color="secondary" />
<Icon className="fa fa-plus-circle" style= color: green[500] />
<Icon className="fa fa-plus-circle" fontSize="small" />
<Icon className="fa fa-plus-circle" style= fontSize: 30 />
</div>
);
【讨论】:
您的答案将在 Icon 组件中导入整个图标,这不是 @SoS 777 想要的。以上是关于动态导入 React Material UI 图标的主要内容,如果未能解决你的问题,请参考以下文章
如何替换 react-material-ui datepicker 的导航图标?
React - Material-UI Accordion:如何使标题居中并展开图标
不能将 React.lazy 与 Material UI 图标一起使用
React FontAwesome 图标不喜欢 Material-UI 工具提示