Trying to dynamically load SVG's but getting a Runtime Error, and not sure what the issue is. Can anyone help out?
Component:
import React, { useEffect, useRef } from "react";
import { IIcon } from './IIcon';
import {
DEFAULT_ASSET_ICON_FOLDER,
} from '@/constants/default';
function Icon({name}: IIcon) {
const ImportedIconRef = useRef();
useEffect(() => {
const importIcon = async () => {
try {
ImportedIconRef.current = (
await import(`${DEFAULT_ASSET_ICON_FOLDER}/${name}.svg`)
).ReactComponent;
} catch (err) {
// @TODO - Log error somewhere
}
};
importIcon();
}, [name]);
const SvgIcon = ImportedIconRef.current;
return (
<SvgIcon />
);
}
export default Icon;
Usage: I just want to pass in a string based reference to the file name.
<Icon name="DELETE" />
Error This is the error I'm getting back, referring to Element type is invalid
Unhandled Runtime Error
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `Icon`.
CodePudding user response:
You're returning an null / undefined <SvgIcon />
while the svg is being loaded.
- Add a
loading
state variable & update it infinally
block.
const [, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
const importIcon = async () => {
try {
ImportedIconRef.current = (
await import(`./${DEFAULT_ASSET_ICON_FOLDER}/${name}.svg`)
).ReactComponent;
} catch (err) {
// @TODO - Log error somewhere
// console.log(err);
} finally {
setLoading(false);
}
};
importIcon();
}, [name]);
- Add a null check
if (SvgIcon) {
return <SvgIcon />;
}
return null;