在create-react-app项目中将SVG作为ReactComponent导入时变得不确定

时间:2019-06-19 17:21:34

标签: reactjs svg create-react-app

尝试将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",

我的代码在下面。

Icon.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;

custom.d.ts

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

tsconfig.json

{
  "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"
  ]
}

任何建议都值得赞赏。

5 个答案:

答案 0 :(得分:1)

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

要导入SVG,请执行以下操作:import MySvg from "MySvg.svg",它将在MySvg中将路径另存为字符串。

要渲染它,请像在标准HTML中一样使用img标签,因为MySvg实际上是路径:<img src={MySvg}/>

未定义的原因是您正在破坏字符串。

答案 1 :(得分:0)

使用这种方式 例如,找到您的svg并将其放入此功能

您的svg文件

interface IProps {
  fill?: string;
}
export default (props: IProps) => (
  <svg
    style={{ marginTop: "13px" }}
    fill={props.fill || Primary}
    viewBox="0 0 424 424"
    width={15}
  >
    <path d="M35,89C15,89,0,74,0,54s15-36,35-36h353c20,0,36,16,36,36s-16,35-36,35H35z" />
    <path d="M388,176c20,0,36,16,36,36s-16,35-36,35H35c-20,0-35-15-35-35s15-36,35-36H388z" />
    <path d="M388,335c20,0,36,15,36,35s-16,36-36,36H35c-20,0-35-16-35-36s15-35,35-35H388z" />
  </svg>
);

您要使用svg的地方

import React from "react";
import Menu from "./assets/svg/menu";

 ...
 return (
   ...
   <Menu/> 
 )

答案 2 :(得分:0)

尝试使用Styled components

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

这个正在工作

答案 3 :(得分:0)

如何使用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.

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

答案 4 :(得分:0)

如果您需要将SVG作为组件导入React中,我建议使用此工具https://react-svgr.com/playground/ 否则,应对SVG的最简单方法就是上面其他答案中提到的方法。