Reputation: 59
I have a large array of categories and a variable whose value is one of the categories, lets say
const categories = ['a1', 'a2', ..., 'a200'];
const category = 'a57';
I have a svg file corresponding to each category name: 'a1.svg', 'a2.svg', ..., 'a200.svg'
My problem is that, I need to render only one svg file, based on a variable that comes from categories array and I can't render it as image, because I need to be able to change it's fill/stroke value.
<img src={`./images/${category}.svg} />
I tried to import all the svgs like this
import {ReactComponent as a1} from './images/ai.svg';
and put all those imports in array. But when I did it this way, I had an array of objects like this. In theory I could work with that, but some of my categories had spaces and other symbols and I couldn't use .render.name value since you can't import like this {ReactComponent as martial arts}. It's also uncomfortable cause I need to do a lot of imports instead of doing something like
const images = categories.map(category => {
return {
name: category,
svg: require(`./images/${category}.svg`
}
})
I also tried to make an array of objects which would look like this
const images = [ {name: 'a1', svg: a1}, {name: 'a2', svg: a2} ];
and render it as
{images.find(img => img.name === category).svg}
but I couldn't cause it would give me this error
Error: Objects are not valid as a React child (found: object with keys {$$typeof, render}). If you meant to render a collection of children, use an array instead.
Render only one svg component based on the category variable that's value could be anything from the categories array. Also, how to correctly import those svgs in a way that would allow me to easily render the svg and change its fill/stroke value in CSS.
Something similiar to making an import like this to work
import {ReactComponent as imageCategory} from `./images/${category}.svg`
Upvotes: 3
Views: 2342
Reputation: 13078
Error: Objects are not valid as a React child (found: object with keys {$$typeof, render}). If you meant to render a collection of children, use an array instead.
This occurs because you are not rendering the component, you are just getting the component instance:
const Svg = images.find(img => img.name === category).svg //--> component instance
return <Svg /> //--> render it
//--> **Note:** this just an example it won't work because it won't find the module.
If you are using Webpack
, you can use require.context:
const svgDir = require.context("!@svgr/webpack!./images");
const images = categories.map(category => {
return {
name: category,
svg: svgDir(`./${category}.svg`).default
}
});
then:
const renderImgByCategory = (category) => {
const Svg = images.find(img => img.name === category).svg;
return <Svg/>
}
JSX:
{renderImgByCategory(category)}
Upvotes: 2