繁体   English   中英

在React中动态创建组件

[英]Dynamically create components in React

我正在使用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:类型无效-预期为字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。 您可能忘记了从定义文件中导出组件,或者可能混淆了默认导入和命名导入。

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

无输出


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 ,还有更多错误。

在React开发工具中输出

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

在React开发工具中输出

<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,但似乎没有一个对我有用,这就是为什么我要一个新的问题。 我也尝试过搜索错误,但也没有运气。

在给定react-icons名称的情况下,以下是动态创建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命名转换。

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

暂无
暂无

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

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