¿Cómo mostrar un archivo SVG en React Native?


104

Quiero mostrar archivos svg (tengo un montón de imágenes svg) pero no pude encontrar la manera de mostrar. Intenté usar los componentes Image y Use de react-native-svg pero no funcionan con eso. E intenté hacer eso de forma nativa, pero es muy difícil mostrar solo una imagen svg.

Código de ejemplo:

import Svg, {
  Use,
  Image,
} from 'react-native-svg';

<View>
  <Svg width="80" height="80">
     <Image href={require('./svg/1f604.svg')} />
  </SvgRn>
</View>

También sé que el react native no es compatible con svg básicamente, pero creo que alguien solucionó este problema de forma complicada (con / sin react-native-svg)


No puede usar use para mostrar un archivo completo, necesitaría una imagen para eso.
Robert Longson

Sí, también lo probé @RobertLongson pero tampoco funciona.
the_bluescreen

Puede agregarlo como css backgroundImage, ¿lo probó?
danielarend

Lo intenté, pero reaccioné, el componente de vista nativo no es compatible con la función backgroundImage en el estilo css. @danielarend
the_bluescreen

No estoy seguro de por qué usaría un contenedor SVG para envolver una imagen SVG.
Robert Longson

Respuestas:


70

Usé la siguiente solución:

  1. Convierta la .svgimagen a JSX con https://svg2jsx.herokuapp.com/
  2. Convierta el JSX en un react-native-svgcomponente con https://svgr.now.sh/ (marque la casilla de verificación "React Native")

¿Cómo usar ese componente entonces? ¿Puedes compartir un código?
Indranil Dutta

Si sigue este enlace verá un ejemplo con importaciones svgr.now.sh (marque la casilla de verificación "React Native). Úselo como un componente React normal, colóquelo en lugar de <Image src = {...} /> y debería funcionar.
Ihor Burlachenko

1
@IhorBurlachenko cuando cansé su solución, recibí este error Error no detectado: Violación invariante: El tipo de elemento no es válido: se esperaba una cadena (para componentes integrados) o una clase / función pero obtuve: objeto . ¿podrías ayudarme aquí?
Mighty

2
Cualquiera que tenga problemas para usar este enfoque, asegúrese de instalar la última versión del react-native-svgpaquete. También asegúrese de ejecutar este comando para vincular su paquetereact-native link react-native-svg
connect2Coder

2
Este es un proceso largo para implementar archivos SVG, mejor use github.com/kristerkari/react-native-svg-transformer como se sugiere a continuación stackoverflow.com/a/55604442/1854104
hefgi

10

Publiqué otra solución aquí, que es el mejor enfoque para insertar un gráfico vectorial (svg) en una aplicación nativa de reacción . Este enfoque usa una fuente vectorial (de svg) en lugar de un archivo svg. PD: Funciona muy bien en iOS y Android, y también puede cambiar el color y el tamaño de su icono vectorial.

Si desea insertar un svg directamente en su aplicación, puede probar una biblioteca de terceros: react-native-svg. Con más de 3000 estrellas en github, es uno de los mejores enfoques.

  • Instalar en pc:
    • npm reacciono-native-svg
    • npm reacciono-native-svg-uri
  • vincular el nativo:
    • react-native link react-native-svg

Y aquí tienes una muestra:

import * as React from 'react';
import SvgUri from 'react-native-svg-uri';
import testSvg from './test.svg';
export default () => (
  <SvgUri
    width="200"
    height="200"
    svgXmlData={testSvg}
  />
);

Da un error "no se puede agregar un niño que no tiene un nodo CSS a un nodo sin una función de medida".
Pulkit Aggarwal

Usé el último con source = {require ('myImagePath')} pero me da un error.
Pulkit Aggarwal

1
Mira la respuesta que publico aquí, usando una fuente en lugar de un svg. es una mejor solución: stackoverflow.com/questions/49951885/…
Cassio Seffrin

2
Esta biblioteca es tan lenta. Envuelve cada svg en su propia vista web.
JP_

1
tnx, esta fue la solución más rápida, pero en lugar de svgXmlData = {testSvg} usé source = {testSvg} funcionó como un encanto. tnx de nuevo.
Andris Laduzans

9

Después de probar muchas formas y bibliotecas, decidí crear una nueva fuente (con Glyphs o este tutorial ) y agregarle mis archivos SVG, luego usar el componente "Texto" con mi fuente personalizada.

Espero que esto ayude a cualquiera que tenga el mismo problema con SVG en react-native.


Creo que tiene razón, una familia de fuentes es probablemente la forma más fácil de conseguir en svgs simples reaccionan nativa
Joe Lloyd

Buen tutorial sobre ese tema: blog.bam.tech/developper-news/… . Requiere el paquete Vector Icons Node.
Rafa

Esta solución no es válida si necesita importar un archivo sag multicolor
Joe Aspara

Probé su solución con icomoon y no funcionó ni su soporte está activo. Y fontello está alterando mis svgs.
Siraj Alam

6

Instalar react-native-svg-transformer

npm reacciono-native-svg-transformer --save-dev

Estoy usando SVG de la siguiente manera y funciona bien

import LOGOSVG from "assets/svg/logo.svg"

en render

<View>
  <LOGOSVG 
    width="100%"
    height="70%"
  />
</View>

Cuando estoy importando el archivo svg HEARTSVG de la carpeta de imágenes, aparece un error. Y no hay error al importar archivos png. ¿Cualquier sugerencia?
Rakesh

4

Yo tuve el mismo problema. Estoy usando esta solución que encontré: React Native display SVG from a file

No es perfecto, y lo estoy revisando hoy, porque funciona mucho peor en Android.


En realidad, es una respuesta creativa, pero no ayuda a mis ajustes :) Porque usaré la lista de íconos (10 o más íconos SVG), así que si uso esto, supongo que puede ser realmente malo para el rendimiento. ¿Qué piensas?
the_bluescreen

Representé 10-15 svgs en una página. Nadie se quejó en iOS, todos se quejaron en Android. En iOS hay un retraso de 0,1 a 0,3 segundos (un destello de una fracción de segundo de color blanco antes de que se cargue). En Android puede ser de 1 segundo y, a veces, nunca se cargan. Al final verifiqué mis SVG, luego escribí un script que los convierte a PNG del tamaño exacto usando svg2png . Luego se usa <Image>con esos PNG. Dado el estado actual de SVG en react native, no hay ETA para que los SVG funcionen, por lo que esta es su mejor opción si no puede tolerar el trabajo.
Sledge Hammer

3

Utilice https://github.com/kristerkari/react-native-svg-transformer

En este paquete se menciona que los .svgarchivos no son compatibles con React Native v0.57 y versiones anteriores, así que use la .svgxextensión para archivos svg.

Para web o react-native-web, utilice https://www.npmjs.com/package/@svgr/webpack


Para renderizar archivos svg react-native-svg-uricon react-native versión 0.57 y anteriores, debe agregar los siguientes archivos a su proyecto raíz

Nota: cambie la extensión svgasvgx

paso 1: agregue el archivo transformer.jsa la raíz del proyecto

// file: transformer.js

const cleanupSvg = require('./cleanup-svg');

const upstreamTransformer = require("metro/src/transformer");

// const typescriptTransformer = require("react-native-typescript-transformer");
// const typescriptExtensions = ["ts", "tsx"];

const svgExtensions = ["svgx"]

// function cleanUpSvg(text) {
//   text = text.replace(/width="([#0-9]+)px"/gi, "");
//    text = text.replace(/height="([#0-9]+)px"/gi, "");
//    return text;
// }

function fixRenderingBugs(content) {
  // content = cleanUpSvg(content); // cleanupSvg removes width and height attributes from svg
  return "module.exports = `" + content + "`";
}


module.exports.transform = function ({ src, filename, options }) {
  // if (typescriptExtensions.some(ext => filename.endsWith("." + ext))) {
  //  return typescriptTransformer.transform({ src, filename, options })
  // }

  if (svgExtensions.some(ext => filename.endsWith("." + ext))) {
    return upstreamTransformer.transform({
      src: fixRenderingBugs(src),
      filename,
      options
    })
  }

  return upstreamTransformer.transform({ src, filename, options });
}

paso 2: agregar rn-cli.config.jsa la raíz del proyecto

module.exports = {
    getTransformModulePath() {
      return require.resolve("./transformer");
    },
    getSourceExts() {
      return [/* "ts", "tsx", */ "svgx"];
    }
  };

Las soluciones mencionadas anteriormente también funcionarán en aplicaciones de producción ✅


2

He probado todas las soluciones anteriores y otras soluciones fuera de la pila y ninguna me ha funcionado. finalmente, después de una larga investigación, encontré una solución para mi proyecto de exposición.

Si necesita que funcione en expo, una solución podría ser usar https://react-svgr.com/playground/ y mover la extensión de accesorios a un elemento G en lugar de la raíz SVG de esta manera:

import * as React from 'react';
import Svg, { G, Path } from 'react-native-svg';

function SvgComponent(props) {
  return (
    <Svg viewBox="0 0 511 511">
      <G {...props}>
        <Path d="M131.5 96c-11.537 0-21.955 8.129-29.336 22.891C95.61 132 92 149.263 92 167.5s3.61 35.5 10.164 48.609C109.545 230.871 119.964 239 131.5 239s21.955-8.129 29.336-22.891C167.39 203 171 185.737 171 167.5s-3.61-35.5-10.164-48.609C153.455 104.129 143.037 96 131.5 96zm15.92 113.401C142.78 218.679 136.978 224 131.5 224s-11.28-5.321-15.919-14.599C110.048 198.334 107 183.453 107 167.5s3.047-30.834 8.581-41.901C120.22 116.321 126.022 111 131.5 111s11.28 5.321 15.919 14.599C152.953 136.666 156 151.547 156 167.5s-3.047 30.834-8.58 41.901z" />
        <Path d="M474.852 158.011c-1.263-40.427-10.58-78.216-26.555-107.262C430.298 18.023 405.865 0 379.5 0h-248c-26.365 0-50.798 18.023-68.797 50.749C45.484 82.057 36 123.52 36 167.5s9.483 85.443 26.703 116.751C80.702 316.977 105.135 335 131.5 335a57.57 57.57 0 005.867-.312 7.51 7.51 0 002.133.312h48a7.5 7.5 0 000-15h-16c10.686-8.524 20.436-20.547 28.797-35.749 4.423-8.041 8.331-16.756 11.703-26.007V503.5a7.501 7.501 0 0011.569 6.3l20.704-13.373 20.716 13.374a7.498 7.498 0 008.134 0l20.729-13.376 20.729 13.376a7.49 7.49 0 004.066 1.198c1.416 0 2.832-.4 4.07-1.2l20.699-13.372 20.726 13.374a7.5 7.5 0 008.133 0l20.732-13.377 20.738 13.377a7.5 7.5 0 008.126.003l20.783-13.385 20.783 13.385a7.5 7.5 0 0011.561-6.305v-344a7.377 7.377 0 00-.146-1.488zM187.154 277.023C171.911 304.737 152.146 320 131.5 320s-40.411-15.263-55.654-42.977C59.824 247.891 51 208.995 51 167.5s8.824-80.391 24.846-109.523C91.09 30.263 110.854 15 131.5 15s40.411 15.263 55.654 42.977C203.176 87.109 212 126.005 212 167.5s-8.824 80.391-24.846 109.523zm259.563 204.171a7.5 7.5 0 00-8.122 0l-20.78 13.383-20.742-13.38a7.5 7.5 0 00-8.131 0l-20.732 13.376-20.729-13.376a7.497 7.497 0 00-8.136.002l-20.699 13.373-20.727-13.375a7.498 7.498 0 00-8.133 0l-20.728 13.375-20.718-13.375a7.499 7.499 0 00-8.137.001L227 489.728V271h8.5a7.5 7.5 0 000-15H227v-96.5c0-.521-.054-1.03-.155-1.521-1.267-40.416-10.577-78.192-26.548-107.231C191.936 35.547 182.186 23.524 171.5 15h208c20.646 0 40.411 15.263 55.654 42.977C451.176 87.109 460 126.005 460 167.5V256h-.5a7.5 7.5 0 000 15h.5v218.749l-13.283-8.555z" />
        <Path d="M283.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15zM331.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15zM379.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15zM427.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15z" />
      </G>
    </Svg>
  );
}

export default function App() {
  return (
    <SvgComponent width="100%" height="100%" strokeWidth={5} stroke="black" />
  );
}

Esto también está funcionando bien para mí. Podemos obtener fácilmente la ruta del archivo svg abriéndolo en el navegador y ver la fuente de la página y luego usar directamente la ruta y reemplazar la etiqueta <ruta /> con react-native-svg <Ruta />. MUCHAS GRACIAS
Rakesh

0

Nota: Svg no funciona para las versiones de lanzamiento de Android, así que no lo considere para Android. Funcionará para Android solo en modo de depuración. Pero funciona bien para iOS.

Utilice https://github.com/vault-development/react-native-svg-uri

Instalar en pc

npm install react-native-svg-uri --save
react-native link react-native-svg # not react-native-svg-uri

Uso

import SvgUri from 'react-native-svg-uri';


<SvgUri source={require('./path_to_image/image.svg')} />

@AravindVemula tienes razón. No funciona para las versiones de lanzamiento de Android. Tampoco pude encontrar una solución. Probablemente no haya solución hasta ahora. Dejé el uso de svg y volví a la forma tradicional de reaccionar imágenes nativas
Daniel Raouf

0

Yo uso estos dos complementos

  1. [react-native-svg] https://github.com/react-native-community/react-native-svg )
  2. [react-native-svg-transformer] https://github.com/kristerkari/react-native-svg-transformer )

En primer lugar, debe instalar ese complemento. Después de eso, debe cambiar su metro.config.js, con este código.

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"]
    }
  };
})();

Para más detalles, puede visitar este enlace


0

puede convertir cualquier SVG en un componente y hacerlo reutilizable.

aquí está mi respuesta de la forma más fácil de hacerlo

SVG al componente


0
import React from 'react'
import SvgUri from 'react-native-svg-uri';

export default function Splash() {
  return (
    <View style={styles.container}>
      {/* provided the svg file is stored locally */}
      <SvgUri
        width="400"
        height="200"
        source={require('./logo.svg')}
      />
      {/* if the svg is online */}
      <SvgUri
        width="200"
        height="200"
        source={{ uri: 'http://thenewcode.com/assets/images/thumbnails/homer-simpson.svg' }}
      />

      <Text style={styles.logoText}>
        Text
      </Text>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  logoText: {
    fontSize: 50
  }
});

utilizar npm install react-native-svg-uri --savepara instalar el paquete necesario
bello hargbola

-6

Todas estas soluciones son absolutamente horribles. Simplemente convierta su SVG a PNG y use el <Image/>componente vainilla . El hecho de que react-native todavía no admita imágenes SVG en el Imagecomponente es una broma. Nunca debe instalar una biblioteca adicional para una tarea tan simple. Utilice https://svgtopng.com/


1
Es un proyecto de código abierto; estoy seguro de que estarán felices con su solicitud de extracción si tiene una solución mejor que la mencionada anteriormente ... :)
Herald Smit
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.