这里有一些错误。
'ReactComponent' 引用了一个值,但在此处被用作类型。
你在链接的答案中看到的 ReactComponent
实际上是在通过 Create React App 加载 .svg
文件时的一个属性。这是一个非常棒的功能,我今天第一次学习到它!
在那个 示例代码 中。
import { ReactComponent as Logo } from './logo.svg';
他们正在做的是从'./logo.svg'导入中获取
ReactComponent
属性并将其重命名为
Logo
。
你的
import {ReactComponent} from '*.svg';
没有太多意义。
当使用
ReactComponent
作为类型时,会出现“类型作为值”的错误,因为它不是一种类型。你试图用
.then((Icon as ReactComponent)
进行类型断言,应该改为
.then((Icon as React.ComponentType<SomePropsType>)
。
JSX元素类型'Icon'没有任何构造或调用签名。
让我们花点时间看看我们实际从
import
语句中得到了什么。
import(`../../assets/icons/${name}.svg`).then(console.log);
你应该看到一个具有三个属性的对象:
ReactComponent
,
default
和
Url
。
{
ReactComponent: ƒ SvgLogo(),
default: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0i...",
Url: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0i..."
}
default
导入的 svg 文件(也是 Url
属性)是图像的 data-url。您可以在 img
的 src
属性中使用它。
ReactComponent
是我们需要的属性!这就是 Create React App 将 svg 转换为 React 组件的地方。(注意:名称“SvgLogo”取决于文件名)。
从渲染中未返回任何内容。
您的 SvgIcon
函数没有返回任何内容。您的 return
语句是 then
回调的返回值。
处理异步 import
有点棘手,因为您在第一次渲染时不会得到值。在这种情况下,我们可以返回 null
(或者您可能想返回一个大小占位符)。
在这里,我使用 element
状态来存储返回的元素。它最初为 null
,在加载后被替换为 <Icon/>
。
我正在使用依赖于您的props的useEffect
内部调用import
。一旦导入解析完成,我们就可以从res.ReactComponent
获取Icon
。
Icon
的推断类型是any
,这对您来说可能没问题。如果您想要准确的类型,可以使用混乱的as React.ComponentType<JSX.IntrinsicElements['svg']>;
,它表示“这是一个React组件,它接受<svg>
元素的所有props”。
import * as React from "react";
interface SVGIconProps {
width: string | number;
color: string;
name: string;
}
const SvgIcon: React.FC<SVGIconProps> = ({ width, color, name }) => {
const [element, setElement] = React.useState<JSX.Element | null>(null);
React.useEffect(() => {
import(`./icons/${name}.svg`).then((res) => {
const Icon = res.ReactComponent as React.ComponentType<JSX.IntrinsicElements['svg']>;
setElement(<Icon fill={color} width={width} />);
});
}, [name, color, width]);
return element;
};
export default SvgIcon;