简体   繁体   English

动态导入 React Material UI 图标

[英]Import React Material UI Icons dynamically

The main idea is to only import react material UI icons when it is needed or rather when dynamically where we wouldn't know the icon name at compile time.主要思想是仅在需要时导入反应材质 UI 图标,或者在编译时我们不知道图标名称时动态导入。 (Let's gurentee that we would have valid icon names). (让我们保证我们会有有效的图标名称)。

My approach was to use a require statment with dynamic path:我的方法是使用带有动态路径的 require 语句:

const IconComponent = require(`@material-ui/icons/${icon}`).default;

This works fine but some warnings are showing up.这工作正常,但出现了一些警告。

./node_modules/@material-ui/icons/utils/createSvgIcon.d.ts 3:8 Module parse failed: Unexpected token (3:8) You may need an appropriate loader to handle this file type. ./node_modules/@material-ui/icons/utils/createSvgIcon.d.ts 3:8 模块解析失败:意外令牌 (3:8) 您可能需要适当的加载程序来处理此文件类型。 | | import SvgIcon from '@material-ui/core/SvgIcon';从“@material-ui/core/SvgIcon”导入 SvgIcon; | | declare function createSvgIcon(path: React.ReactNode, displayName: string): typeof SvgIcon;声明 function createSvgIcon(path: React.ReactNode, displayName: string): typeof SvgIcon; | | | | export default createSvgIcon;导出默认 createSvgIcon;

./node_modules/@material-ui/icons/index.d.ts 4:5 Module parse failed: Unexpected token (4:5) You may need an appropriate loader to handle this file type. ./node_modules/@material-ui/icons/index.d.ts 4:5 模块解析失败:意外令牌 (4:5) 您可能需要适当的加载程序来处理此文件类型。 | | import SvgIcon from '@material-ui/core/SvgIcon';从“@material-ui/core/SvgIcon”导入 SvgIcon; | |

type SvgIconComponent = typeof SvgIcon;类型 SvgIconComponent = 类型 SvgIcon; | | | | export const AccessAlarm: SvgIconComponent;导出常量 AccessAlarm:SvgIconComponent;

My question is: How could we avoid these warnings and do the dynamic import in the appropriate way?我的问题是:我们如何避免这些警告并以适当的方式进行动态导入?

You can create a hook for this.您可以为此创建一个挂钩 like the following.像下面这样。

//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/>



please note : import * as icons from '@material-ui/icons' is the same as const * as icons = require('@material-ui/icons').default;请注意import * as icons from '@material-ui/icons'const * as icons = require('@material-ui/icons').default;


option 2选项 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>
  );
}

first is首先是

(async () => {
  if (somethingIsTrue) {
    const { default: myDefault, foo, bar } = await 
import('/modules/my-module.js');
  }
})();

second method is第二种方法是

let module = await import('/modules/my-module.js');

nice working example you can tweak is您可以调整的很好的工作示例是

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;
    });
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM