您可以使用ref和ReactComponent导入SVG文件时命名为出口。请注意,它必须是ref为了它的工作。
以下示例使用需要版本v16.8及更高版本的 React 钩子。
示例动态 SVG 导入挂钩:
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 };
}

typescript中的动态 SVG 导入钩子示例:
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 };
}

对于那些谁是得到undefined了ReactComponent时,SVG动态进口的,这是由于一个错误,其中的WebPack插件添加ReactComponent到以某种方式进口不会触发动态进口各SVG。
基于此解决方案,我们可以通过在动态 SVG 导入中强制使用相同的加载器来临时解决该问题。
唯一的区别是ReactComponent现在是default输出。
ImportedIconRef.current = (await import(`!!@svgr/webpack?-svgo,+titleProp,+ref!./${name}.svg`)).default;
另请注意,使用带有可变部分的动态导入时存在限制。这个 SO 答案详细解释了这个问题。
要解决此问题,您可以使动态导入路径更加明确。
例如,代替
// App.js
<Icon path="../../icons/icon.svg" />
// Icon.jsx
...
import(path);
...
你可以把它改成
// App.js
<Icon name="icon" />
// Icon.jsx
...
import(`../../icons/${name}.svg`);
...