gpt4 book ai didi

javascript - 如何动态导入 SVG 并内联渲染

转载 作者:行者123 更新时间:2023-12-01 15:19:11 25 4
gpt4 key购买 nike

我有一个接受一些参数并呈现 SVG 的函数。我想根据传递给函数的名称动态导入该 svg。它看起来像这样:

import React from 'react';

export default async ({name, size = 16, color = '#000'}) => {
const Icon = await import(/* webpackMode: "eager" */ `./icons/${name}.svg`);
return <Icon width={size} height={size} fill={color} />;
};
根据 webpack documentation for dynamic imports和神奇的评论“渴望”:

"Generates no extra chunk. All modules are included in the currentchunk and no additional network requests are made. A Promise is stillreturned but is already resolved. In contrast to a static import, themodule isn't executed until the call to import() is made."


这就是我的图标解决的问题:
> Module
default: "static/media/antenna.11b95602.svg"
__esModule: true
Symbol(Symbol.toStringTag): "Module"
试图以我的函数试图给我这个错误的方式呈现它: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.我不明白如何使用这个导入的模块将其渲染为组件,或者甚至可以这样吗?

最佳答案

您可以使用refReactComponent导入 SVG 文件时命名导出。请注意,它必须是 ref为了让它工作。
以下示例使用需要版本 v16.8 的 React 钩子(Hook)。以上。
示例动态 SVG 导入钩子(Hook):

function useDynamicSVGImport(name, options = {}) {
const ImportedIconRef = useRef();
const [loading, setLoading] = useState(false);
const [error, setError] = useState();

const { onCompleted, onError } = options;
useEffect(() => {
setLoading(true);
const importIcon = async () => {
try {
ImportedIconRef.current = (
await import(`./${name}.svg`)
).ReactComponent;
if (onCompleted) {
onCompleted(name, ImportedIconRef.current);
}
} catch (err) {
if (onError) {
onError(err);
}
setError(err);
} finally {
setLoading(false);
}
};
importIcon();
}, [name, onCompleted, onError]);

return { error, loading, SvgIcon: ImportedIconRef.current };
}
Edit react-dynamic-svg-import
typescript 中的示例动态 SVG 导入钩子(Hook):
interface UseDynamicSVGImportOptions {
onCompleted?: (
name: string,
SvgIcon: React.FC<React.SVGProps<SVGSVGElement>> | undefined
) => void;
onError?: (err: Error) => void;
}

function useDynamicSVGImport(
name: string,
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 {
ImportedIconRef.current = (
await import(`./${name}.svg`)
).ReactComponent;
onCompleted?.(name, ImportedIconRef.current);
} catch (err) {
onError?.(err);
setError(err);
} finally {
setLoading(false);
}
};
importIcon();
}, [name, onCompleted, onError]);

return { error, loading, SvgIcon: ImportedIconRef.current };
}
Edit react-dynamic-svg-import-ts

对于那些获得 undefined的人对于 ReactComponent当动态导入 SVG 时,这是由于 Webpack 插件添加了 ReactComponent 的错误。以某种方式导入的每个 SVG 不会触发动态导入。
基于此 solution ,我们可以通过在您的动态 SVG 导入中强制使用相同的加载器来临时解决它。
唯一的区别是 ReactComponent现在是 default输出。
ImportedIconRef.current = (await import(`!!@svgr/webpack?-svgo,+titleProp,+ref!./${name}.svg`)).default;

另请注意,使用带有可变部分的动态导入时存在限制。 This SO answer详细解释了这个问题。
要解决此问题,您可以使动态导入路径更加明确。
例如,代替
// App.js
<Icon path="../../icons/icon.svg" />

// Icon.jsx
...
import(path);
...
您可以将其更改为
// App.js
<Icon name="icon" />

// Icon.jsx
...
import(`../../icons/${name}.svg`);
...

关于javascript - 如何动态导入 SVG 并内联渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61339259/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com