从数组渲染 Material-UI 图标

xab*_*bra 2 reactjs material-ui

背景信息:
我正在使用 react 和 material-ui。
为了保持代码干净,我从 const 数组填充菜单项,如下所示:

const menuItems = [
  { label: "Home", path: "/home" },
  { label: "Accounts", path: "/accounts" },
  { label: "Organizations", path: "/organizations" },
];
Run Code Online (Sandbox Code Playgroud)

数组中的每一项都是一个包含标签和重定向路径的对象。我在渲染时映射项目。非常基本。

问题:
我想在 menuItems 数组中包含一个 material-ui 图标组件,以便可以在标签旁边呈现图标。但是我找不到通过名称字符串来引用图标的方法
https://material-ui.com/components/material-icons/

可能的解决方案:

  1. 将图标组件放入一个字符串中: { label: "Accounts", path: "/accounts" }, icon: "<AccountBox/>"}但是我不知何故需要将该字符串评估为 jsx。我不知道怎么做

  2. 制作一个反应功能组件,根据道具呈现不同的图标,例如:<IconSwitch icon = {"accountIcon"} />并在 RFC 内硬编码不同的图标。不漂亮,但应该工作。

  3. Punt 和使用不同的图标,例如可以通过名称字符串引用的 svg 图标或字体图标。

关于如何做到这一点的任何建议?谢谢

Zac*_*ber 5

图标字体

您可以使用该Icon组件。https://material-ui.com/components/icons/#icon-font-icons

要使用图标,只需用 Icon 组件包裹图标名称(字体连字),例如:

import Icon from '@material-ui/core/Icon';

<Icon>star</Icon>
Run Code Online (Sandbox Code Playgroud)

https://codesandbox.io/s/material-demo-forked-sj66h?file=/demo.tsx

假设您使用适当的图标连字设置菜单项:

  const menuItems = [
    { label: "Home", path: "/home", icon: "home" },
    { label: "Accounts", path: "/accounts", icon: "account_circle" },
    { label: "Organizations", path: "/organizations", icon: "settings" }
  ];
Run Code Online (Sandbox Code Playgroud)

然后你可以映射它们:

      {menuItems.map(({ label, icon }) => {
        return (
          <span key={label}>
            {label} <Icon>{icon}</Icon>
          </span>
        );
      })}
Run Code Online (Sandbox Code Playgroud)

SVG 图标

如果您想使用 SVG 图标而不是基本图标,我建议您只提取您计划使用的 SVG 图标,以允许您不使用的图标从生成的包中摇树。摇树的能力是在字体图标上使用 SVG 图标的一个很好的理由。

import { Home, AccountCircle, Settings, AddCircle } from "@material-ui/icons";
Run Code Online (Sandbox Code Playgroud)

如果你想允许的所有图标用户输入或不属于该图标将显示时间提前知道,你可以导入所有@material-ui/icons乔纳森的回答

如果您没有将图标列表放入需要能够字符串化的内容中(即 Redux/通过 API 调用发送),那么您可以直接将图标放入数组并呈现它们:

  const menuItems: MenuItem[] = [
    { label: "Home", path: "/home", icon: <Home /> },
    { label: "Accounts", path: "/accounts", icon: <AccountCircle /> },
    { label: "Organizations", path: "/organizations", icon: <Settings /> }
  ];

 // Rendering:

      {menuItems.map(({ label, icon }) => {
        return (
          <span key={label}>
            {label} {icon}
          </span>
        );
      })}

Run Code Online (Sandbox Code Playgroud)

如果您要将图标放在需要字符串化的地方,则上述方法将不起作用,因此我建议将您要使用的图标放入对象中以映射它们。这样你就有了一个图标映射的字符串。

示例:https : //codesandbox.io/s/material-icons-svg-udcv3?file=/demo.tsx

import { Home, AccountCircle, Settings, AddCircle } from "@material-ui/icons";

const icons = {
  Home,
  AccountCircle,
  Settings
};
Run Code Online (Sandbox Code Playgroud)

在上面的例子中(即从数组中渲染图标)

interface MenuItem {
  label: string;
  path: string;
  icon: keyof typeof icons;
}

  const menuItems: MenuItem[] = [
    { label: "Home", path: "/home", icon: "Home" },
    { label: "Accounts", path: "/accounts", icon: "AccountCircle" },
    { label: "Organizations", path: "/organizations", icon: "Settings" }
  ];

// Rendering:

      {menuItems.map(({ label, icon }) => {
        const Icon = icons[icon];
        return (
          <span key={label}>
            {label} <Icon />
          </span>
        );
      })}
Run Code Online (Sandbox Code Playgroud)

  • 杰出的。这有效。只需要在 index.html 文件中包含 `&lt;link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" /&gt;` 即可获取 Material Icons 字体。 - - 谢谢你! (2认同)