React NativeでSVGを使う方法: react-native-svg + SvgXml実践ガイド
SVG(Scalable Vector Graphics)は、React Native開発で重要なグラフィック形式です。PNG/JPGなどのビットマップ画像と比べて、SVGは拡大縮小で劣化せず、容量を抑えやすく、スタイルの動的制御もしやすいという利点があります。
この記事では、React NativeでSVGを扱う代表的な2つの方法を、コード例と運用上の注意点とあわせて紹介します。
React NativeでSVGを使う理由
SVGには次のメリットがあります。
- 高解像度対応: 画面サイズや解像度が変わってもシャープ
- 容量効率: 複数解像度PNGを持つより軽くなることが多い
- 動的スタイル: propsで色・サイズなどを変更可能
- 表示一貫性: iOS / Androidで同じ見た目にしやすい
基本依存: react-native-svg
React NativeでSVGを使う最初のステップは react-native-svg の導入です。
npm install react-native-svg
# or
yarn add react-native-svg
補足: React Native 0.60以上では自動リンクされることが多く、旧バージョンでは手動リンクが必要な場合があります。
方法1: react-native-svg-transformerを使う
最も推奨される方法で、Web ReactのようにSVGをコンポーネントとして直接importできます。
インストールと設定
まずtransformerを追加します。
npm install --save-dev react-native-svg-transformer
# or
yarn add --dev 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"],
},
};
})();
使用例
設定後は、SVGをそのままimportして使えます。
import React from "react";
import { View } from "react-native";
import Logo from "./assets/logo.svg";
const MyComponent = () => (
<View>
<Logo width={100} height={100} fill="#3B82F6" />
</View>
);
export default MyComponent;
メリット:
- 型安全で開発体験が良い
- propsによる動的スタイル制御が容易
- ビルド時変換でパフォーマンスが安定
向いているケース: 静的アイコンセット、デザインシステムの固定アセット
方法2: SvgXmlで動的に描画する
react-native-svg の SvgXml は、XML文字列からSVGを描画できるため、動的な場面に向いています。
基本例
import React from "react";
import { SvgXml } from "react-native-svg";
const svgMarkup = `
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="#10B981" />
</svg>
`;
const DynamicIcon = () => <SvgXml xml={svgMarkup} width="100%" height="100%" />;
export default DynamicIcon;
ファイルから動的に読み込む例
ファイルシステムやネットワークからSVGを読む場合にも有効です。
import React, { useState, useEffect } from "react";
import { SvgXml } from "react-native-svg";
import RNFS from "react-native-fs";
const LoadableSvg = ({ filePath }) => {
const [xml, setXml] = useState("");
useEffect(() => {
async function loadSvg() {
try {
const svgContent = await RNFS.readFile(filePath);
setXml(svgContent);
} catch (error) {
console.error("Error loading SVG file", error);
}
}
loadSvg();
}, [filePath]);
return xml ? <SvgXml xml={xml} width="100%" height="100%" /> : null;
};
メリット:
- 実行時の動的ロードに対応
- APIや外部サーバーからの取得に適用可能
- ユーザー生成コンテンツにも柔軟
注意点: 実行時にXMLを解析するため、複雑SVGを頻繁に再描画すると性能に影響する場合があります。
SVGファイルの配置と管理
React Nativeでは通常 assets 配下にSVGを置いて管理します。
推奨構成:
src/
assets/
icons/
arrow-left.svg
arrow-right.svg
logos/
brand-primary.svg
brand-secondary.svg
components/
icon.tsx
SVG Viewerで事前確認する
React Nativeへ組み込む前に SVG Viewer で確認すると、実装後の手戻りを減らせます。
- viewBox確認: 切れやスケール崩れの予防
- 不要要素削除: メタデータやエディタ付加情報の除去
- パス確認: パスデータの欠損や冗長性の確認
- スケール確認: 複数サイズで視認性チェック
パフォーマンス最適化のポイント
React NativeでSVGを使う場合は最適化が重要です。
- パス簡略化: SVG Optimizer やSVGOを活用
- 未使用要素削除: 非表示レイヤーや空グループを削除
- 重複スタイル統合: 繰り返し属性を整理
- 精度制御: 座標小数点を2-3桁程度に調整
最適化済みSVGは読み込みと描画が安定し、特にリスト表示など高頻度描画で効果が出ます。
実務向けの運用提案
- 命名規則を統一: 例
icon-home.svg,logo-brand.svg - 共通Iconコンポーネント化: importと利用を集約
- TypeScript型定義: SVGコンポーネントのDX改善
- 遅延読み込み戦略: 大規模アイコンセットは必要時ロード
まとめ
React NativeでSVGを扱う方法は複数あります。用途に応じて使い分けるのが最適です。
- 静的アイコン中心: react-native-svg-transformer
- 動的コンテンツ中心: SvgXml
- 性能重視: 事前最適化と複雑度管理
どの方法でも、導入前にSVG Viewerで品質を確認する運用を入れると、端末上の表示不具合を大きく減らせます。
Next Steps
- SVG Viewer でviewBox、配置、スケールを確認
- SVG Optimizer で複雑度を下げて描画を安定化
- SVG to React Native でコンポーネントコードを生成