简体   繁体   English

React:动态导入 svg 作为组件

[英]React: Import svg as component dynamically

In my application I got 8 svg files which I want to import dynamically.在我的应用程序中,我得到了 8 个想要动态导入的 svg 文件。 I have tried the following:我尝试了以下方法:

First I created a Floor component that has one name prop.首先,我创建了一个具有一个名称 prop 的 Floor 组件。 This is the name of the floor that the user wants to see.这是用户想要查看的楼层名称。 In my dynamic import, the path to the svg is specified but it always seems to return undefined.在我的动态导入中,指定了 svg 的路径,但它似乎总是返回未定义。

I know the path to the svg is correct because if I fill in a wrong path, React complains it can't find the svg file.我知道 svg 的路径是正确的,因为如果我填写了错误的路径,React 会抱怨它找不到 svg 文件。

import React, { useEffect, useState } from "react";

const Floor = ({ name }) => {

  const [floor, setFloor] = useState(null);

  useEffect(() => {

    /*
    This is where it goes wrong. If I log the result It shows 'undefined'.
    */

    import(`./floors/${name}.svg`)
      .then((module) => {
        setFloor(module);
      })
      .catch((error) => {
        console.error(`Icon with name: ${name} not found!`);
      });
  }, [name]);

  const renderFloor = () => {
    if (!floor) return null;

    const Floor = floor.ReactComponent;

    return <Floor />;
  };

  return <>{renderFloor()}</>;
}

export default Floor;

And this is how I import the Floor这就是我导入地板的方式

import Floor from './Floor'

const Floorplan = () => {

  return (
    <Floor name="floor-4" />
  )
}

export default Floorplan;

I have found something similar but I still have the same error 'undefined'我发现了类似的东西,但我仍然有同样的错误“未定义”

These are the errors Im getting.这些是我得到的错误。
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.错误:元素类型无效:应为字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。 You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。

And if I log the dynamic import response:如果我记录动态导入响应:

Object { loaded: Getter, id: Getter, exports: undefined, webpackPolyfill: 1 } Icon.js:14 Object { 加载:Getter,id:Getter,导出:未定义,webpackPolyfill:1 } Icon.js:14

I believe the problem is webpack cannot determine what your ${name}.svg will look like in runtime and does not include them inside any chunk.我相信问题是webpack无法确定您的${name}.svg在运行时的样子,并且不将它们包含在任何块中。 To force this behavior you should include somemagic comments inside your dynamic import.要强制执行此行为,您应该在动态导入中包含一些magic comments Something like:就像是:

  ...
  useEffect(() => {
    import(
      /* webpackInclude: /\.svg$/ */
      /* webpackChunkName: "svg-imgs-chunk" */
      /* webpackMode: "lazy" */
      `./floors/${name}.svg`)
      .then((module) => {
        setFloor(module);
      })
  ...

The below worked for me.以下对我有用。 I had my svgs in a folder inside src , and was using the companyName prop for the svg filename.我将我的 svgs 放在src内的文件夹中,并使用companyName属性作为svg文件名。 I also used a regex to format companyName to all lower case and no space (like the svg filenames)我还使用正则表达式将companyName格式化为全部小写且没有空格(如 svg 文件名)

  const [iconUrl, setIconUrl] = useState(false)

  const { companyName } = job.companyByCompany

  useEffect(() => {
    iconFetch(companyName.toLowerCase().replace(/\s+/g, ''))
  }, [companyName])

  const iconFetch = async (iconName) => {
    await import(`../assets/logos/${iconName}.svg`)
    .then(data => setIconUrl(data.default))
    .catch(err => console.log(err))
  }

I could then access the svg's via the src attribute in an img tag.然后我可以通过img标签中的src属性访问 svg。

<img src={iconUrl} alt={`${companyName} svg`}/>

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

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