I have react component named IconRenderer
and I’m passing 2 props named iconName
and iconPath
. What the IconRenderer do is it imports react-icon
module using lazyload by taking the iconPath
and iconName
The following is my IconRenderer component
type Props = {
iconName: string;
iconPath: string;
};
const IconRenderer = (props: Props) => {
const { iconName, iconPath } = props;
const path = `react-icons/${iconPath}`
const Icon = lazy(async () => {
const module = await import(path);
return { default: module[iconName] };
});
console.log(Icon);
return (
<Suspense fallback={<div>Loading...</div>}>
<IconContext.Provider value={{ size: "3em" }}>
<Icon />
</IconContext.Provider>
</Suspense>
);
};
export default IconRenderer;
I’m using this IconRenderer component in the APP.tsx as below
<IconRenderer iconName="FaAccessibleIcon" iconPath="fa" />
When importing the module, it says the following error
Cannot find module 'react-icons/fa'
Anyhow when importing the module by directly passing the path without assigning it to a variable as below, it works
const Icon = lazy(async () => {
const module = await import(`react-icons/fa`);
console.log(module)
return { default: module[iconName] };
});
What i want is to import the module by taking the variable path
2
Answers
This ensures that the dynamic import uses the correct path at runtime. Storing the path in a variable (
const path = react-icons/${iconPath}
) may lead to issues, especially if the dynamic import is unable to resolve the path correctly in certain situations.I don’t think, this will be a good idea to have this kind of a component for rendering icons dynamically.
Most of the time as a developer, we tend to create constants or some sort of reference for assets like icons, images, fonts, or any other frequently used string. So, I think you should create an index of all the icons in one place like this.
Then, we don’t have to worry about inconsistent icons all over the app. We can reference the index and change it once, every other instance of it will also be updated.
Then, we can create a wrapper component, that wraps the icons with the styles we might need. We can add here default styles that will be applied to all.
And we can use this component and add styles specific to use cases, later on while using the Wrapper.
This feels much more intuitive and we are writing re-usable components and constants, which can be used over and over with customized styles.
I hope you find this way of rendering icons helpful. Let me know if you liked it this way.