简体   繁体   中英

Cannot get SVG as a component to render in CRA

I've written the following TypeScript component:

import React from 'react'
import cx from 'classnames'

/* import SVGs */
import { ReactComponent as Phone } from '../images/phone.svg' 
import { ReactComponent as AtDesk } from '../images/at-desk.svg' 
import { ReactComponent as Available } from '../images/available.svg' 
import { ReactComponent as Blushing } from '../images/blushing.svg' 
import { ReactComponent as Skills } from '../images/skills.svg' 
import { ReactComponent as Smile } from '../images/smile.svg' 
import { ReactComponent as Beach } from '../images/beach.svg' 

const selectMiniMe = (name: string): any => {
    switch (name) {
      case 'available' :
        return <Available />
      case 'at-desk':
        return <AtDesk/>
      case 'blushing':
        return <Blushing />
      case 'skills':
        return <Skills />
      case 'phone':
        return <Phone />
        case 'beach':
          return <Beach />
      case 'smile':
      default:
        return <Smile />
    }
  }

/* Import Types */
import Props from './types/props'

/* import Styles */
import styles from './styles.module.scss'

/* Render Component */
export const MiniMe: React.FC<Props> = ({ name, width, position, classes}: Props) => {
  return <div className={cx(styles['mini-me'], styles[`w-${width}`], classes)}>
    { selectMiniMe(name) }
    </div>
}


export default MiniMe

This component renders without issue as a story in storybook. Everything looks and works exactly as expected and no errors are reported.

When I try to import that component into a brand new Create-React-App TypeScript app. I get the following error:

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.

Check the render method of `MiniMe`.

I suspect the issue is loader related but as far as I can tell, I'm doing everything the way that CRA is already configured to work with so I have no idea where it's failing.

For additional reference, here is a link to the repo:https://github.com/foxleigh81/alex-foxleigh-portfolio/tree/2020

I've also managed to find a reference to this exact issue - which as far as I can tell was actually fixed in CRA in 2018, so I've no idea why I'm getting this issue here: https://github.com/facebook/create-react-app/pull/5573

Try to declare the svg module

add this to // / <reference types="react-scripts" /> declare module '*.svg'; in your react-app-env.d.ts file.

Looking at your repository it seems you are using learna and react setup and are not using create-react-app completely , as I don't see all dependencies that are added to new react app created using create-react-app there in your codebase and hence I am not sure using svg as component will work.

That being said, that will not prevent you from using img tag. I have updated your code and it is working as expected:

import React from 'react'
import cx from 'classnames'

/* Import Types */
import Props from './types/props'

/* import SVGs */
import Phone from './images/phone.svg' 
import AtDesk from './images/at-desk.svg' 
import Available from './images/available.svg' 
import Blushing from './images/blushing.svg' 
import Skills from './images/skills.svg' 
import Smile from './images/smile.svg' 
import Beach from './images/beach.svg' 


/* import styles */
import styles from './styles.module.scss'

/* Render component */
export const MiniMe: React.FC<Props> = ({ name, width, position, classes}: Props) => {
  const selectMiniMe = (name: string): any => {
    switch (name) {
      case 'available' :
        return <img src={Available} />
      case 'at-desk':
        return <img src={AtDesk} />
      case 'blushing':
        return <img src={Blushing} />
      case 'skills':
        return <img src={Skills} />
      case 'phone':
        return <img src={Phone} />
        case 'beach':
          return <img src={Beach} />
      case 'smile':
      default:
        return <img src={Smile} />
    }
  }

  return <div className={cx(styles['mini-me'], styles[`w-${width}`], classes)}>
    {selectMiniMe(name)}
    </div>
}

export default MiniMe

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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