基本的に、私がやりたいことは、SVG アイコンを React コンポーネントにインポートし、それにプロパティを追加することです。size="24px"
コンポーネントとしてより柔軟にしたいです。または、className
プロパティを追加して CSS で編集できるようにします (たとえば、hover プロパティを追加できます)。Webpack で TypeScript を使用するのは初めてなので、SVG 要素の型をどのように宣言すればよいのか混乱しており、エラーが発生します (以下を参照)。
SVG を組み込む方法はたくさんあるので、ReactComponent としてインポートすることにしました。
メニューアイコン.svg
<svg width="24" height="24" viewBox="0 0 24 24">
<path fill="currentColor" fillRule="evenodd" d="M4.5 5h15a.5.5 0 1 1 0 1h-15a.5.5 0 0 1 0-1zm0 6h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 6h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1z"></path>
</svg>
header.tsx (ここでは svg アイコンを使用します)
import React from 'react';
import MenuIcon from '../assets/menu-icon.svg';
const Header: React.SFC = () => {
return (
<header className="c-header u-side-paddings">
<MenuIcon className="c-header__icon" /> // <-- className prop doesn't match provided type
</header>
);
};
export default Header;
index.d.ts (.svg ファイルをコンポーネントとして扱うことができる)
declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
MenuIcon SVG コンポーネントに prop を追加するとclassName
エラーが発生します。
(JSX attribute) className: string
Type '{ className: string; }' is not assignable to type 'IntrinsicAttributes'.
Property 'className' does not exist on type 'IntrinsicAttributes'.ts(2322)
これまでの私の理解
- div内にsvgコンポーネントをラップして、
className
次のように追加することもできます<div className="c-header__icon"><MenuIcon/></div>
が、これはエレガントではない解決策であり、あまり良い方法ではないと思います。 - 私は学んだこの答えSVG プロパティはオブジェクトなので文字列ではありません
SVGAnimatedString
。つまり: index.d.ts
.svg の代わりに .tsx ファイルを作成しようとしましたが (その場合は ファイルは必要ありません)、className
のタイプがの場合にのみ機能しますstring
。また、 とは異なる拡張子のファイルに SVG アイコンを保存するのが良い方法かどうかはわかりません.svg
。私の意見では、それは明確さのために良くありません。私が間違っている場合は、実際に良い方法を教えてください。例を示します。
import React from 'react';
interface MenuIcon {
className?: SVGAnimatedString;
}
export class MenuIcon extends React.PureComponent<MenuIcon> {
render() {
return (
<svg width="24" height="24" viewBox="0 0 24 24">
<path fill="currentColor" fillRule="evenodd" d="M4.5 5h15a.5.5 0 1 1 0 1h-15a.5.5 0 0 1 0-1zm0
6h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 6h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1z"></path>
</svg>
);
}
}
基礎が足りないような気がします。いくつかのトピックが組み合わさっているので、何に焦点を当てるべきか判断するのが本当に難しいです。
ベストアンサー1
私はこの問題に直面していましたが、この解決策はうまくいきました:
declare module "*.svg" {
import { FC, SVGProps } from "react";
const content: FC<SVGProps<SVGElement>>;
export default content;
}
それに、私は@svgr/ウェブパックNext.jsとともにSVGローダーとして