在React

时间:2018-03-21 11:53:49

标签: javascript reactjs

我正在使用react-icons,我有一个JSON文件,如下所示:

social: {
  twitter: {
    icon: 'FaTwitter',
    link: 'twitterlink',
  },
  linkedin: {
    icon: 'FaLinkedIn',
    link: 'linkedinlink',
  },
  github: {
    icon: 'FaGithub',
    link: 'githublink',
  },
}

我试图通过循环遍历JSON来动态创建图标,但是我在使它工作时遇到了很多麻烦。

以下是我到目前为止已经尝试过的片段以及控制台中产生的输出和错误:

反应图标导入

import * as FontAwesome from 'react-icons/lib/fa';

1

{Object.keys(social).map(key => {
  let IconName = Component['FontAwesome.' + social[key].icon];

  return (
    <li key={key}>
      <a href={social[key].link} target="_blank" rel="noopener">
        <IconName size="15" />
      </a>
    </li>
  );
})}
  

警告:React.createElement:type无效 - 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:undefined。您可能忘记从其定义的文件中导出组件,或者您可能混淆了默认导入和命名导入。

     

未捕获错误:元素类型无效:期望字符串(对于内置组件)或类/函数(对于复合组件)但得到:undefined。您可能忘记从其定义的文件中导出组件,或者您可能混淆了默认导入和命名导入。

无输出

2

{Object.keys(social).map(key => {
  let IconName = FontAwesome`.${social[key].icon}`;

  return (
    <li key={key}>
      <a href={social[key].link} target="_blank" rel="noopener">
        <IconName size="15" />
        {/* This line produces the same result */}
        {/* {React.createElement(IconName, { size: '15' })} */}
      </a>
    </li>
  );
})}
  

未捕获的TypeError:__WEBPACK_IMPORTED_MODULE_1_react_icons_lib_fa__不是函数

无输出

第3

{Object.keys(social).map(key => {
  let IconName = `FontAwesome.${social[key].icon}`;

  return (
    <li key={key}>
      <a href={social[key].link} target="_blank" rel="noopener">
        <IconName size="15" />
      </a>
    </li>
  );
})}
  

警告:<FontAwesome.FaTwitter />正在使用大写HTML。始终在React中使用小写HTML标记。

     

警告:此浏览器中无法识别标记<FontAwesome.FaTwitter>。如果您要渲染React组件,请使用大写字母开始其名称。

还有更多错误,但FaLinkedInFaGithub的错误相同。

在反应工具中输出

<li>
  <a href="twitterlink" target="_blank" rel="noopener">
    <Fontawesome.FaTwitter size="15"></Fontawesome.FaTwitter>
  </a>
</li>

HTML输出

<li>
  <a href="twitterlink" target="_blank" rel="noopener">
    <fontawesome.fatwitter size="15"></fontawesome.fatwitter>
  </a>
</li>

我想要的是这样的:

<FontAwesome.FaTwitter size="15" />

在反应工具中输出

<FaTwitter size="15">
  <IconBase viewBox="0 0 40 40" size="15">
    <svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="15" width="15" viewBox="0 0 40 40" style="vertical-align: middle;">
      <g>
        <path d="m37.7 9.1q-1.5 2.2-3.7 3.7 0.1 0.3 0.1 1 0 2.9-0.9 5.8t-2.6 5.5-4.1 4.7-5.7 3.3-7.2 1.2q-6.1 0-11.1-3.3 0.8 0.1 1.7 0.1 5 0 9-3-2.4-0.1-4.2-1.5t-2.6-3.5q0.8 0.1 1.4 0.1 1 0 1.9-0.3-2.5-0.5-4.1-2.5t-1.7-4.6v0q1.5 0.8 3.3 0.9-1.5-1-2.4-2.6t-0.8-3.4q0-2 0.9-3.7 2.7 3.4 6.6 5.4t8.3 2.2q-0.2-0.9-0.2-1.7 0-3 2.1-5.1t5.1-2.1q3.2 0 5.3 2.3 2.4-0.5 4.6-1.7-0.8 2.5-3.2 3.9 2.1-0.2 4.2-1.1z">
        </path>
      </g>
    </svg>
  </IconBase>
</FaTwitter>

HTML输出

<svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="15" width="15" viewBox="0 0 40 40" style="vertical-align: middle;">
  <g>
    <path d="m37.7 9.1q-1.5 2.2-3.7 3.7 0.1 0.3 0.1 1 0 2.9-0.9 5.8t-2.6 5.5-4.1 4.7-5.7 3.3-7.2 1.2q-6.1 0-11.1-3.3 0.8 0.1 1.7 0.1 5 0 9-3-2.4-0.1-4.2-1.5t-2.6-3.5q0.8 0.1 1.4 0.1 1 0 1.9-0.3-2.5-0.5-4.1-2.5t-1.7-4.6v0q1.5 0.8 3.3 0.9-1.5-1-2.4-2.6t-0.8-3.4q0-2 0.9-3.7 2.7 3.4 6.6 5.4t8.3 2.2q-0.2-0.9-0.2-1.7 0-3 2.1-5.1t5.1-2.1q3.2 0 5.3 2.3 2.4-0.5 4.6-1.7-0.8 2.5-3.2 3.9 2.1-0.2 4.2-1.1z">
    </path>
  </g>
</svg>

我正在尝试做什么?是否有任何变通方法或其他方法?

StackOverflow也有类似的问题,但似乎没有一个对我有用,这就是我问一个新问题的原因。我也尝试使用谷歌搜索错误,但也没有运气。

1 个答案:

答案 0 :(得分:2)

以下是如何使用图标名称动态创建react-icons

import React from "react";
import { render } from "react-dom";
import * as FontAwesome from "react-icons/lib/fa";

const Icon = props => {
  const { iconName, size, color } = props;
  const icon = React.createElement(FontAwesome[iconName]);
  return (
    <div style={{ fontSize: size, color: color }}>{icon}</div>
  );
};

一旦你有这个图标包装器,只需将它用作普通的React组件:
<Icon iconName={"FaBeer"} size={12} color="orange" />
图标名称应遵循MixedCaps命名转换。

此链接是上述代码的代码盒演示:https://codesandbox.io/s/o715x22m4z