React Native에서 SVG 파일을 표시하는 방법은 무엇입니까?


102

나는 svg 파일을 보여주고 싶지만 (나는 많은 svg 이미지를 가지고 있지만) 보여줄 방법을 찾을 수 없었습니다. react-native-svg 의 Image 및 Use 구성 요소 를 사용하려고 시도했지만 작동하지 않습니다. 네이티브 방식으로 시도했지만 svg 이미지 만 보여주는 것은 정말 힘든 일입니다.

예제 코드 :

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

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

또한 반응 네이티브가 기본적으로 svg를 지원하지 않는다는 것을 알고 있지만 누군가가 까다로운 방법 으로이 문제를 해결했다고 생각합니다 (react-native-svg 포함 / 제외)


전체 파일을 표시하는 데 사용할 수는 없습니다. 이미지가 필요합니다.
— Robert Longson

예, @RobertLongson도 시도했지만 작동하지 않습니다.
— the_bluescreen

css backgroundImage로 추가 할 수 있습니다. 시도 했습니까?
— danielarend

시도했지만 네이티브 View 구성 요소가 CSS 스타일의 backgroundImage 소품을 지원하지 않습니다. @danielarend
— the_bluescreen

SVG 이미지를 래핑하기 위해 SVG 래퍼를 사용하는 이유를 잘 모르겠습니다.
— Robert Longson

답변:


70

다음 솔루션을 사용했습니다.

  1. https://svg2jsx.herokuapp.com/.svg 을 사용하여 이미지를 JSX로 변환
  2. https://svgr.now.sh/ 를 사용하여 JSX를 react-native-svg구성 요소로 변환합니다 ( "React Native 확인란 선택).

그러면 해당 구성 요소를 어떻게 사용합니까? 코드를 공유 할 수 있습니까?
— Indranil Dutta

이 링크를 따라 가면 imports svgr.now.sh ( "React Native 체크 박스 선택) 예제를 볼 수 있습니다 . 일반 React 컴포넌트로 사용하고 <Image src = {...} /> 대신 배치합니다. 그것은 작동합니다.
— 호르 Burlachenko에게

1
@IhorBurlachenko 내가 솔루션을 지쳤을 때이 오류가 발생했습니다 Uncaught Error : Invariant Violation : Element type is invalid : expected a string (for built-in components) or a class / function but got : object . 여기서 도와 주실 수 있나요?
— Mighty

2
이 방법을 사용하는 데 문제가있는 사람은 최신 버전의 react-native-svg패키지를 설치했는지 확인하십시오 . 또한 패키지를 연결하려면이 명령을 실행해야합니다react-native link react-native-svg
— connect2Coder

2
이것은 SVG 파일을 구현하는 긴 프로세스입니다. 아래에 제안 된대로 github.com/kristerkari/react-native-svg-transformer 를 더 잘 사용 하십시오. stackoverflow.com/a/55604442/1854104
— hefgi

10

여기 에 벡터 (svg) 그래프를 반응 기본 응용 프로그램에 삽입하는 가장 좋은 방법 인 또 다른 솔루션을 게시했습니다. .이 방법은 svg 파일 대신 벡터 글꼴 (svg에서)을 사용합니다. 추신 : iOS 및 Android에서 잘 작동하며 벡터 아이콘의 색상과 크기를 변경할 수도 있습니다.

SVG를 앱에 직접 삽입하려면 타사 라이브러리 인 react-native-svg를 사용해 볼 수 있습니다. github에서 3k 이상의 별을 사용하는 것은 최고의 접근 방식 중 하나입니다.

  • 설치:
    • npm i react-native-svg
    • npm i react-native-svg-uri
  • 네이티브에 연결 :
    • 반응 네이티브 링크 react-native-svg

다음은 샘플입니다.

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}
  />
);

"측정 기능이없는 노드에 CSS 노드가없는 자식을 추가 할 수 없습니다"라는 오류가 발생합니다.
— Pulkit Aggarwal

마지막 하나를 source = {require ( 'myImagePath')}와 함께 사용했지만 오류가 발생합니다.
— Pulkit Aggarwal

1
svg 대신 글꼴을 사용하여 여기에 게시하는 답변을보십시오. 그것은 더 나은 솔루션입니다 : stackoverflow.com/questions/49951885/...
— 카시오 Seffrin에게

2
이 라이브러리는 너무 느립니다. 자체 웹보기에서 모든 svg를 래핑합니다.
— JP_

1
tnx, 이것은 가장 빠른 솔루션 이었지만 svgXmlData = {testSvg} 대신 source = {testSvg}가 매력처럼 작동했습니다. 다시 tnx.
— Andris Laduzans

9

여러 가지 방법과 라이브러리를 시도한 후 새 글꼴 ( Glyphs 또는이 자습서 사용 )을 만들고 여기에 SVG 파일을 추가 한 다음 사용자 정의 글꼴과 함께 "텍스트"구성 요소를 사용하기로 결정했습니다.

이것이 반응 네이티브에서 SVG와 동일한 문제를 가진 모든 사람에게 도움이되기를 바랍니다.


난 당신이 바로 생각, 글꼴 가족으로 간단한 svgs를 얻을 수있는 가장 쉬운 방법은 아마도 기본 반응이다
— 조 로이드

해당 주제에 대한 멋진 튜토리얼 : blog.bam.tech/developper-news/… . 벡터 아이콘 노드 패키지가 필요합니다 .
— Rafa

당신은 멀티 컬러 처짐 파일을 가져해야하는 경우이 솔루션은 유효하지 않습니다
— 조 Aspara

icomoon과 함께 솔루션을 시도했지만 지원이 활성화되지 않았습니다. 그리고 fontello는 내 svg를 변경하고 있습니다.
— Siraj Alam

6

설치를 반응 네이티브-SVG-변압기를

npm i react-native-svg-transformer --save-dev

다음과 같이 SVG를 사용하고 있으며 잘 작동합니다.

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

렌더링 중

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

이미지 폴더에서 SVG 파일 HEARTSVG를 가져올 때 오류가 표시됩니다. 그리고 png 파일을 가져 오는 데 오류가 없습니다. 어떠한 제안?
— Rakesh

4

나는 같은 문제가 있었다. 나는이 솔루션을 사용하고 있습니다 : React Native display SVG from a file

완벽하지 않으며, Android에서 성능이 훨씬 더 나쁘기 때문에 오늘 다시 방문합니다.


실제로 그것은 창의적인 대답이지만 내 적합성에 도움이되지 않습니다. 어떻게 생각해?
— the_bluescreen

한 페이지에 10-15 개의 svg를 렌더링했습니다. 아무도 iOS에 대해 불평하지 않았고 모두가 Android에 대해 불평했습니다. iOS에서는 0.1-0.3 초의 지연이 있습니다 (로드되기 전에 흰색이 두 번째로 깜박임). Android에서는 1 초가 될 수 있으며 때로는로드되지 않습니다. 결국 SVG를 체크인 한 다음 svg2png를 사용하여 정확한 크기의 PNG로 변환하는 스크립트를 작성했습니다 . 그런 다음 <Image>해당 PNG와 함께 사용 됩니다. 반응 네이티브에서 SVG의 현재 상태를 감안할 때 SVG 작동에 대한 ETA가 없으므로 해결 방법을 용인 할 수없는 경우 이것이 최선의 방법입니다.
— Sledge Hammer

3

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

이 패키지에서는 .svg파일이 React Native v0.57 이하에서 지원되지 않는다고 언급 되어 있으므로 .svgxsvg 파일의 확장자를 사용 하십시오.

웹 또는 react-native-web의 경우 https://www.npmjs.com/package/@svgr/webpack을 사용 하십시오.


react-native-svg-urireact-native 버전 0.57 이하를 사용하여 svg 파일을 렌더링하려면 루트 프로젝트에 다음 파일을 추가해야합니다.

참고 : 확장자 svg를 다음으로 변경하십시오.svgx

1 단계 : transformer.js프로젝트의 루트에 파일 추가

// 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 });
}

2 단계 : rn-cli.config.js프로젝트의 루트에 추가

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

위에서 언급 한 솔루션은 프로덕션 앱에서도 작동합니다 .✅


2

위의 모든 솔루션과 스택 외부의 다른 솔루션을 시도했지만 나를 위해 일하지 않았습니다. 마침내 오랜 연구 끝에 엑스포 프로젝트를위한 하나의 해결책을 찾았습니다.

엑스포에서 작업해야하는 경우 한 가지 해결 방법은 https://react-svgr.com/playground/ 를 사용 하고 다음과 같이 SVG 루트 대신 G 요소로 props 확산을 이동하는 것입니다.

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

이것은 또한 나를 위해 잘 작동합니다. svg 파일의 경로를 브라우저에서 열고 페이지 소스를 확인한 다음 경로를 직접 사용하고 <path /> 태그를 react-native-svg <Path />로 대체 할 수 있습니다. 큰 감사
— Rakesh

0

참고 : Svg는 Android 릴리스 버전에서 작동하지 않으므로 Android를 고려하지 마십시오. 디버그 모드에서만 Android에서 작동합니다. 그러나 iOS에서는 잘 작동합니다.

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

설치

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

용법

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


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

@AravindVemula 당신이 맞습니다. Android 릴리스 버전에서는 작동하지 않습니다. 나는 또한 해결책을 찾지 못했습니다. 아마도 지금까지는 해결책이 없을 것입니다. 내가 SVG를 사용하여 포기하고의 전통적인 방법으로 다시 켜지는 기본 이미지를 반응
— 다니엘 라우 프

0

이 두 가지 플러그인을 사용합니다.

  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 )

우선 해당 플러그인을 설치해야합니다. 그런 다음이 코드로 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"]
    }
  };
})();

자세한 내용은이 링크를 참조하십시오.



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
  }
});

사용 npm install react-native-svg-uri --save하여 필요한 패키지 설치
— hargbola 벨로

-6

이 모든 솔루션은 절대적으로 끔찍합니다. SVG를 PNG로 변환하고 바닐라 <Image/>구성 요소를 사용하십시오 . react-native가 여전히 Image컴포넌트 에서 SVG 이미지를 지원하지 않는다는 사실 은 농담입니다. 이러한 간단한 작업을 위해 추가 라이브러리를 설치해서는 안됩니다. https://svgtopng.com/ 사용


1
그것은 오픈 소스 프로젝트입니다-위에서 언급 한 것보다 더 나은 솔루션이 있다면 그들이 당신의 풀 리퀘스트에 만족할 것이라고 확신합니다 ... :)
— Herald Smit
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.