我在React JS中导入SVG文件时遇到了问题。
import { ReactComponent as Logo} from '../logo.svg'
我不知道为什么,在某些组件中<Logo />
可以正确地呈现,而在其他组件中它并不显示。当我使用检查工具时,SVG图像确实存在且占据必要的空间,但SVG图像是空的。是否还有其他人遇到过这个问题?尝试:
import { default as logo } from '../logo.svg';
然后将其用作类型为img的节点中的源,就像这样:
<img src={logo} />
import { ReactComponent as Logo} from '../logo.svg'
<svg><Logo fill="blue" width="100%" height="100%" /></svg>
// or...
<div><Logo fill="blue" width="100%" height="100%" /></div>
<svg>
或<div>
标签包裹它,它会渲染一个空白图像,占据空间但没有任何视觉效果。一旦我加上了包装标签,它就正常工作了。我喜欢这种方法,因为您可以根据用户输入动态更改SVG样式。我遇到了同样的问题,有时候是因为导入方式的问题,我通过以下方式解决:
import {ReactComponent as Icon} from 'pathtoyourfile.svg
然后使用:
<Icon />
然而,有时候SVG文件会有相似的类名和ID名,如果你检查文件,你可能会看到clip0,image0,pattern0等。如果有多个SVG文件,它们的ID和Class名称很有可能会发生冲突并覆盖彼此。对我来说,最简单的解决方案是手动更改命名约定,不确定是否存在更自动化的解决方案?
我查过了,只有create-react-app可以将SVG用作组件
https://create-react-app.dev/docs/adding-images-fonts-and-files/#adding-svgs
注意:此功能仅适用于react-scripts@2.0.0及更高版本和react@16.3.0及更高版本。import React from 'react';
import logo from './logo.png'; // Tell webpack this JS file uses this image
console.log(logo); // /logo.84287d09.png
function Header() {
// Import result is the URL of your image
return <img src={logo} alt="Logo" />;
}
export default Header;
import { ReactComponent as YourSvg } from './logo.svg';
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
issuer: /\.[jt]sx?$/,
use: ["babel-loader", "@svgr/webpack", "url-loader"],
},
interface IconProps extends React.SVGProps<SVGSVGElement> {
name: string;
size?: number;
className?: string;
onCompleted?: UseDynamicSVGImportOptions["onCompleted"];
}
const SVgComponent = ({
name,
size,
className, }: {
name: string;
className?: string;
size: number;
}) => {
function SvgIcon({ onCompleted }: PropsWithChildren<IconProps>) {
const { error, loading, SvgIcon } = useDynamicSVG(name, {
onCompleted,
});
if (error) {
return <>{error.message}</>;
}
if (loading) {
return <>Loading...</>;
}
if (SvgIcon) {
return (
<>
{className ? (
<SvgIcon className={className} />
) : (
<SvgIcon width={size} height={size} className={className} />
)}
</>
);
}
return null;
}
const handleOnCompleted = useCallback(
(iconName: string) => console.log(`${iconName} successfully loaded`),
[]
);
return (
<div className="cartIcon-container">
{/* <ShoppingIcon className="svg-icon" /> */}
<SvgIcon
name={name}
onCompleted={handleOnCompleted}
size={size}
className={className}
/>
</div>
);
};
export default SVgComponent;
并且
export function useDynamicSVG(
name: any,
options: UseDynamicSVGImportOptions = {}
) {
const ImportedIconRef = useRef<React.FC<React.SVGProps<SVGSVGElement>>>();
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error>();
const { onCompleted, onError } = options;
useEffect(() => {
setLoading(true);
const importIcon = async (): Promise<void> => {
try {
const iconTypes = {
cart: (await require(`../../assets/shopping.svg`)).ReactComponent,
logo: (await require(`../../assets/logo_shop.svg`)).ReactComponent,
};
ImportedIconRef.current =
"Cart" === name ? iconTypes.cart : iconTypes.logo;
onCompleted?.(name, ImportedIconRef.current);
} catch (err: any) {
onError?.(err);
setError(err);
} finally {
setLoading(false);
}
};
importIcon();
}, [name, onCompleted, onError]);
return { error, loading, SvgIcon: ImportedIconRef.current };
}