在 create-react-app 项目中将 svg 作为 ReactComponent 导入时未定义

IT技术 reactjs svg create-react-app
2021-05-24 03:00:52

尝试将 svg 加载为 ReactComponent 时出现以下错误。

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

检查 的渲染方法Icon

我正在使用带有typescript选项的 create-react-app 来创建项目。如果我正确理解了文档,我应该能够立即将 svgs 作为 ReactComponent 导入(从 CRA2.0 开始)。但奇怪的是,我对导入的组件没有定义。

添加图像、字体和文件 · 创建 React App https://facebook.github.io/create-react-app/docs/adding-images-fonts-and-files#adding-svgs

目前使用以下软件包。

    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-redux": "^6.0.1",
    "react-router-dom": "^5.0.1",
    "react-scripts": "^3.0.1",
    "@types/node": "^12.0.0",
    "@types/react": "^16.8.17",
    "@types/react-dom": "^16.8.4",
    "@types/react-redux": "^7.0.8",
    "@types/react-router-dom": "^4.3.3",

我的代码如下。

图标.tsx

import * as React from 'react';
import { ReactComponent as IconSvg } from './IconSvg.svg';

const Icon: React.FC<IconProps> = props => {
  console.log(IconSvg); // undefined
  return (<IconSvg />);
};

export default Icon;

自定义.d.ts

declare module '*.svg' {
  import React = require('react');
  export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
  const src: string;
  export default src;
} 

配置文件

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true,
    "baseUrl": "src",
    "rootDir": "src",
    "outDir": "build/dist",
    "target": "es5",
    "jsx": "react",
    "lib": [
      "es6",
      "dom"
    ],
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": false,
    "allowSyntheticDefaultImports": true
  },
  "include": [
    "src",
    "custom.d.ts"
  ],
  "exclude": [
    "node_modules",
    "node_scripts",
    "build",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/setupTests.ts"
  ]
}

任何建议表示赞赏。

4个回答

TLDR:import MySvg from "MySvg.svg"然后 <img src={MySvg}/>

导入 SVG:import MySvg from "MySvg.svg"将路径保存为 .csv 文件中的字符串MySvg

要呈现它,请使用标准 HTML 中的 img 标签,因为MySvg它实际上是一个路径:<img src={MySvg}/>

您未定义的原因是您正在解构字符串。

尝试使用样式化组件

import Logo from 'assets/logo.svg';

const Image = styled.img<Props>`<some setting for standard width and height for logo here`>

const LogoWrapper = styled(Image)`
transition: all 0.25s linear;
&: hover {
    transform: scale(1.25);
}`;

<LogoWrapper height={140} src={Logo} alt="Some Logo" />

这个正在工作

如何使用 Typescript 制作 SVG 的另一个示例:-


export interface ISVG {
    viewBox?: string;
    width?: string;
    height?: string;
    fill?: string;
    className?: string;
}

export const SVG = ({
    viewBox = '0 0 200 200',
    fill = '#FA4D56',
    width,
}: ISVG): JSX.Element => {
    return (
        <svg viewBox={viewBox} width={width}>
            <path
                fill={fill}
                d="M41.9,-43.6C54,-39.8,63.3,-26.3,59.5,-15.3C55.8,-4.2,39,4.3,31.4,18.6C23.7,32.8,25.1,52.8,16,65.4C6.9,78,-12.7,83.2,-25.5,76C-38.4,68.8,-44.5,49,-44.5,33.3C-44.5,17.6,-38.4,6,-37.3,-7.8C-36.3,-21.5,-40.5,-37.4,-35.1,-42.3C-29.8,-47.2,-14.9,-41.3,0,-41.3C14.9,-41.3,29.8,-47.3,41.9,-43.6Z"
                transform="translate(100 100)"
            />
        </svg>
    );
};

您还可以按如下方式导出 SVG:-

export {SVG as Shape}; or w/e naming you choose to export it as.

之后应该应用诸如边距或填充之类的东西,我假设因为您希望它们尽可能通用并且能够在不同的位置重复使用它们。

如果您需要将 SVG 作为组件导入 React,我会推荐这个工具https://react-svgr.com/playground/ 否则在 React中处理 SVG 的最简单方法是上面其他答案提到的方法。