Prithin Babu
Prithin Babu

Reputation: 376

Got this 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?

Upvotes: 12

Views: 21081

Answers (7)

Lasitha Lakmal
Lasitha Lakmal

Reputation: 880

I faced the same issue. In my case, I had done all the code integrations according to the documentation but was still facing the issue.

Then I ended the metro server and started it again clearing the cache

npm start -- --reset-cache

Upvotes: 0

Zishan Ali
Zishan Ali

Reputation: 49

For those facing react-native-svg issue with react-native 0.73.0 and above you need to update react-native-svg-transformer to "^1.5.0" and add following code in metro.config.js

const defaultConfig = getDefaultConfig(__dirname);
const { assetExts, sourceExts } = defaultConfig.resolver;

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

module.exports = mergeConfig(defaultConfig, config);

Upvotes: -1

mermaid
mermaid

Reputation: 153

for expo

1_ install react native svg transformer npm i --save-dev react-native-svg-transformer and npm i react-native-svg

2_ in metro.config.js file

const { getDefaultConfig } = require("expo/metro-config");

module.exports = (() => {
  const config = getDefaultConfig(__dirname);

  const { transformer, resolver } = config;

  config.transformer = {
    ...transformer,
    babelTransformerPath: require.resolve("react-native-svg-transformer")
  };
  config.resolver = {
    ...resolver,
    assetExts: resolver.assetExts.filter((ext) => ext !== "svg"),
    sourceExts: [...resolver.sourceExts, "svg"]
  };

  return config;
})();

3_ for typescript create declarations.d.ts file with this declare

declare module "*.svg" {
    import React from "react";
    import { SvgProps } from "react-native-svg";
    const content: React.FC<SvgProps>;
    export default content;
  }

4_ regarding change fill property : create file .svgrrc and in it

{
  "replaceAttrValues": {
    "#000": "{props.fill}"
  }
}

And then make sure your path tag inside the SVG file fill attribute is the hex code (in this case #000)

5_ kill terminal and run npx expo start --clear

here the configuration for expo and react native apps

https://github.com/kristerkari/react-native-svg-transformer#installation-and-configuration

Upvotes: 0

Prithin Babu
Prithin Babu

Reputation: 376

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

Upvotes: 9

M Mahmud Hasan
M Mahmud Hasan

Reputation: 1173

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.

Upvotes: 6

Ridwan Ajibola
Ridwan Ajibola

Reputation: 1059

  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

Upvotes: 9

buzatto
buzatto

Reputation: 10382

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.

Upvotes: 13

Related Questions