React NativeでSVGファイルを表示するにはどうすればよいですか?


109

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>

また、react nativeが基本的にsvgをサポートしていないことも知っていますが、誰かがこの問題をトリッキーな方法で修正したと思います(react-native-svgの有無にかかわらず)


useを使用してファイル全体を表示することはできません。そのためには、画像が必要です。
ロバートロングソン2016

ええ、私も@RobertLongsonで試しましたが、どちらも機能しません。
the_bluescreen 2016

あなたはそれをcssbackgroundImageとして追加することができます、あなたはそれを試しましたか?
danielarend 2016

試しましたが、react NativeViewコンポーネントはcssスタイルのbackgroundImagepropをサポートしていません。@danielarend
the_bluescreen 2016

SVG画像をラップするためにSVGラッパーを使用する理由がわかりません。
ロバートロングソン2016

回答:


74

私は次の解決策を使用しました:

  1. https://svg2jsx.herokuapp.com/を使用して.svg画像をJSXに変換します
  2. https://svgr.now.sh/react-native-svg使用してJSXをコンポーネントに変換します([React Native]チェックボックスをオンにします)

では、そのコンポーネントをどのように使用するのですか?コードを共有できますか?
Indranil Dutta 2018

このリンクをたどると、imports svgr.now.shの例が表示されます([React Native]チェックボックスをオンにします)。通常のReactコンポーネントとして使用し、<Image src = {...} />の代わりに配置します。それが動作するはずです。
Ihor Burlachenko

1
@IhorBurlachenko私があなたの解決策を疲れさせたとき、私はこのエラーを受け取りましたキャッチされていないエラー:不変の違反:要素タイプが無効です:文字列(組み込みコンポーネントの場合)またはクラス/関数が必要ですが、取得しました:オブジェクト。ここで私を助けてくれませんか?
マイティ

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

ここに別の解決策を投稿しました。これは、react Nativeアプリケーションベクター(svg)グラフを挿入するための最良のアプローチです。このアプローチでは、svgファイルの代わりにベクターフォント(svgから)を使用します。PS:iOSとAndroidでうまく機能します。また、ベクターアイコンの色とサイズを変更することもできます。

svgをアプリに直接挿入する場合は、サードパーティのライブラリreact-native-svgを試すことができます。githubに3kを超える星があるので、これは最良のアプローチの1つです。

  • インストール:
    • npm i react-native-svg
    • npm i react-native-svg-uri
  • をネイティブにリンクします。
    • react-nativeリンク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ノードを持たない子をメジャー関数のないノードに追加することはできません」というエラーが表示されます。
PulkitAggarwal18年

最後のものをsource = {require( 'myImagePath')}で使用しましたが、エラーが発生します。
Pulkit Aggarwal 2018

1
svgの代わりにフォントを使用して、ここに投稿した回答を見てください。それはよりよい解決策だ:stackoverflow.com/questions/49951885/...
カシオSeffrin

2
このライブラリはとても遅いです。すべてのsvgを独自のWebビューでラップします。
JP_

1
tnx、これは最も迅速な解決策でしたが、svgXmlData = {testSvg}の代わりにsource = {testSvg}を使用しました。再びtnx。
AndrisLaduzans20年

9

多くの方法とライブラリを試した後、(グリフまたはこのチュートリアルを使用して)新しいフォントを作成し、それにSVGファイルを追加してから、カスタムフォントで「テキスト」コンポーネントを使用することにしました。

これがreact-nativeのSVGで同じ問題を抱えている人に役立つことを願っています。


あなたが正しいと思います。フォントファミリーは、単純なsvgをネイティブに反応させる最も簡単な方法です
Joe Lloyd

そのテーマに関する素晴らしいチュートリアル:blog.bam.tech/developper-news/…Vector IconsNodeパッケージが必要です。
ラファ2018

マルチカラーサグファイルをインポートする必要がある場合、このソリューションは無効です
Joe Aspara 2018

私はicomoonでその解決策を試しましたが、うまくいきませんでしたし、彼らのサポートもアクティブではありませんでした。そしてfontelloは私のsvgsを変更しています。
Siraj Alam 2018

6

react-native-svg-transformerをインストールします

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ファイルをインポートするためのエラーはありません。なにか提案を?
ラケッシュ

4

私も同じ問題を抱えていました。私が見つけたこのソリューションを使用しています:ファイルからネイティブディスプレイSVGを反応させる

これは完璧ではありません。Androidではパフォーマンスが大幅に低下するため、本日再訪します。


実際にはそれは創造的な答えですが、それは私の適合には役立ちません:)アイコンリスト(10個以上のSVGアイコン)を使用するので、これを使用すると、パフォーマンスに非常に悪い可能性があります。どう思いますか?
the_bluescreen 2016

1ページに10〜15のsvgをレンダリングしました。iOSについては誰も文句を言わず、Androidについては誰もが文句を言った。iOSでは、0.1〜0.3秒の遅延があります(ロードされる前に一瞬白く点滅します)。Androidでは1秒かかる場合があり、ロードされない場合もあります。最後に、SVGをチェックインし、svg2pngを使用して正確に正しいサイズのPNGに変換するスクリプトを作成しました。次に<Image>、それらのPNGで使用されます。反応ネイティブでのSVGの現在の状態を考えると、SVGが機能するためのETAはないため、回避策を許容できない場合は、これが最善の策です。
スレッジハンマー

3

https://github.com/kristerkari/react-native-svg-transformerを使用します

このパッケージでは、.svgファイルはReact Native v0.57以下ではサポートされていないことが記載されている.svgxため、svgファイルには拡張子を使用してください。

Webまたは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"];
    }
  };

上記のソリューションは、本番アプリでも機能します✅


3

上記のすべてのソリューションとスタック外の他のソリューションを試しましたが、どれもうまくいきませんでした。最後に、長い調査の結果、私は博覧会プロジェクトの1つの解決策を見つけました。

Expoで機能する必要がある場合、回避策の1つは、https://react-svgr.com/playground/を使用して、次のようにSVGルートではなくG要素に小道具の拡散を移動することです。

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

1
これは私にとってもうまく機能しています。svgファイルのパスは、ブラウザーで開いてページソースを表示し、パスを直接使用して<path />タグをreact-native-svg <Path />に置き換えることで簡単に取得できます。BIG THANKS
ラケッシュ

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の使用をやめ、ネイティブイメージを反応させる従来の方法に戻りました
DanielRaouf19年

0

私はこれらの2つのプラグインを使用します。

  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

任意のSVGをコンポーネントに変換して、再利用可能にすることができます。

これがあなたがそれをすることができる最も簡単な方法のための私の答えです

コンポーネントへの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必要なパッケージのインストールに使用
bellohargbola20年

0

簡単な方法でこれを行うことができます

まず、インストールを行う必要があります、

  1. npm install -s react-native-svg
  2. react-nativeリンクreact-native-svg
  3. npm install -s 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"]
    }
  };
})();

その後、次のコードを使用して、declarations.d.jsという名前でルートディレクトリに新しいファイルを作成する必要があります。

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

最後に、これはインポートマトです

import USER from "../../assets/icons/user.svg"

そして、これはjsx用です

<USER width="100%" height="100%"/>


-6

これらの解決策はすべて絶対に恐ろしいものです。SVGをPNGに変換し、バニラ<Image/>コンポーネントを使用するだけです。react-nativeがImageコンポーネント内のSVGイメージをまだサポートしていないという事実は冗談です。このような単純なタスクのために追加のライブラリをインストールしないでください。https://svgtopng.com/を使用します


1
これはオープンソースプロジェクトです-上記よりも優れたソリューションがあれば、プルリクエストに満足していると確信しています... :)
HeraldSmit20年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.