'Why am Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: number

I was running this program to display SVG image

import React, { Component } from 'react';
import { View } from 'react-native';
import Expo from './assets/check-mark.svg';
import SVG from 'react-native-svg';

export default class MyApp extends Component {
 render(){
  return (
    <View style={{backgroundColor:"black"}}>
    <Expo width={20}
    height={15} />
    </View>
   );
 }
}

and came across this error Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: number.

How can I resolve this? or is there any other better approach to use SVG image is React Native?



Solution 1:[1]

The best way to display an SVG in react-native(according to me, this is the best and easy method) is:

First install this SVG package: npm i react-native-svg

Secondly,

  • Download the SVG image you need.
  • Open that SVG file as a text file
  • Copy the code from the SVG file and paste it into the below site
  • https://react-svgr.com/playground/
  • Check the check box against React Native on the left side of the website
  • You will get a code on the right side "JSX OUTPUT"
  • Now in your project's asset folder (or wherever you want to save that SVG), create a new JS file and copy-paste the code you got from the "JSX OUTPUT" side.
  • Save this file and use it as a custom component in your project.

PS: No need to install the SVG transformer package

Solution 2:[2]

For svg files react-native-svg suggests the usage of react-native-svg-transformer.

install the package:

yarn add --dev react-native-svg-transformer

add the configuration to metro.config.js:

const { getDefaultConfig } = require('metro-config');

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
  };
})();

With that your you should be able to render your SVG files.

Solution 3:[3]

  1. Check metro.config.js file

const {getDefaultConfig} = require('metro-config');

module.exports = (async () => {
  const {
    resolver: {sourceExts, assetExts},
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
    },
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
  };
})();

  1. Stop metro bundler or clear metro bundler cache

  2. Rebuild the app again using yarn run ios

Solution 4:[4]

I was facing the same problem after installing all the required package. But after stopping metro bundler and rebuilding the project my issue automatically resolved.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Prithin Babu
Solution 2 buzatto
Solution 3 Ridwan Ajibola
Solution 4 Menon Hasan