SVGをReactで表示したい！！SVGをコンポーネントにする利点と注意点

# はじめに
アドベントカレンダー4日目🎄
サークルのアドベントカレンダーは[こちら](https://qiita.com/advent-calendar/2024/rits_rcc)です！ぜひご覧ください

Web開発において、アイコンやイラストを表示する際にSVG（Scalable Vector Graphics）形式の画像を使用することが一般的になっています。SVGはベクター形式の画像であり、拡大・縮小しても画質が劣化しないという利点があります。

本記事では、SVGファイルをReactで表示する方法と、SVGをコンポーネントとして扱う利点について説明します。具体的な実装例として、鉛筆のアイコン（`pencil.svg`）をReactコンポーネント化し、再利用可能な形で使用する方法を解説します。

# 利点

SVGをReactコンポーネントとして扱うことで、以下のような利点があります。

1. **再利用性の向上**：コンポーネント化することで、同じSVGアイコンを複数の場所で簡単に再利用できます。

2. **プロパティの動的変更**：サイズや色などの属性をプロパティ（props）として渡すことで、柔軟に表示を変更できます。

3. **一貫性の確保**：コンポーネント化することで、プロジェクト全体でアイコンのスタイルや使い方を統一できます。


# 実装

それでは、実際に`pencil.svg`をReactコンポーネントとして扱う方法を見ていきましょう。

## 1. SVGファイルの準備

まずは、以下の`pencil.svg`ファイルを用意します。このSVGは、鉛筆のアイコンを表しています。

```svg
<svg
  width="35"
  height="35"
  viewBox="0 0 35 35"
  fill="none"
  xmlns="http://www.w3.org/2000/svg"
>
  <path
    d="M26.25 2.9165L32.0833 8.74984"
    stroke="white"
    stroke-width="2"
    stroke-linecap="round"
    stroke-linejoin="round"
  />
  <path
    d="M10.9375 29.8957L27.7083 13.1248L21.875 7.2915L5.10413 24.0623L2.91663 32.0832L10.9375 29.8957Z"
    stroke="white"
    stroke-width="2"
    stroke-linecap="round"
    stroke-linejoin="round"
  />
</svg>
```

## 2. Reactコンポーネントへの変換

このSVGを`PenIcon`というReactコンポーネントに変換します。サイズや色を変更できるように、`size`と`color`というプロパティを受け取るようにします。

```tsx
import React from "react";

interface PenIconProps {
  size?: number;
  color?: string;
}

export const PenIcon = ({
  size = 35,
  color = "black",
  ...props
}: PenIconProps) => {
  return (
    <svg
      width={size}
      height={size}
      viewBox="0 0 35 35"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      aria-label="PenIcon"
      role="img"
      {...props}
    >
      <path
        d="M26.25 2.9165L32.0833 8.74984"
        stroke={color}
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M10.9375 29.8957L27.7083 13.1248L21.875 7.2915L5.10413 24.0623L2.91663 32.0832L10.9375 29.8957Z"
        stroke={color}
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
};
```

## 3. 注意点

:::note alert
**注意**

SVGをそのままReactに移植すると、属性名がキャメルケース（小文字始まりの単語を連結し、先頭以外の単語の頭文字を大文字にする形式）に変換されていないため、エラーが発生します。

具体的には、以下の属性名を変更する必要があります。

- `stroke-width` → `strokeWidth`
- `stroke-linecap` → `strokeLinecap`
- `stroke-linejoin` → `strokeLinejoin`

これらの属性名を正しく変換しないと、以下のようなエラーが発生します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748983/db1edf96-d187-01ff-e054-9ba5be5269f2.png)

これは、JSXやTSX内での属性名はキャメルケースで記述する必要があるためです。属性名を適切に修正することで、このエラーを解消できます。
:::

## 4. コンポーネントの使用

作成した`PenIcon`コンポーネントを他のコンポーネントやページで使用する際は、以下のようにインポートして使用します。

```tsx
import React from "react";
import { PenIcon } from "./PenIcon";

const ExampleComponent = () => {
  return (
    <div>
      {/* デフォルトの大きさと色で表示 */}
      <PenIcon />

      {/* サイズを50、色を赤に変更して表示 */}
      <PenIcon size={50} color="red" />
    </div>
  );
};

export default ExampleComponent;
```

これにより、サイズや色を柔軟に変更しながら、同じアイコンを再利用できます。

# 最後に
SVGファイルをReactコンポーネントとして扱うことで、再利用性や可読性が向上し、開発効率も高まります。特に、デザインの一貫性を保ちながら、アイコンやイラストをプロジェクト全体で統一的に使用できる点は大きなメリットです。

また、プロパティを通じて動的に属性を変更できるため、ユーザーの操作や状態に応じてアイコンの見た目を変えることも容易です。

本記事で紹介した方法を参考に、皆さんのプロジェクトでもSVGコンポーネントを活用してみてください。
それではみなさんよいエンジニアライフを〜👋