Reputation: 401
I have the following list of React components and can't change this format.
How could I render this list on my page by looping over it in some way?
const allComponents = isValid => [
{
Component: (
<ComponentA
isTransparent={true}
/>
),
},
{
Component: (
<div>
{<ComponentB/>}
</div>
),
},
!isValid && {
Component: (
<div>
{<ComponentC/>}
</div>
),
},
].filter(Boolean);
Within my return block tried the following:
return (
<Fragment>
{allComponents(false).map(c => (
{c}
))}
</Fragment>
);
End up with following error.
Error! Objects are not valid as a React child.
(found: object with keys {c}). If you meant to render a collection of children, use an array instead.
But the above allComponents is an array.
Could I please get some advice on this pls.
Upvotes: 1
Views: 64
Reputation: 12919
The JSX stored in the the array returned by allComponents()
needs to be returned from a valid function component. You can either turn the Component
properties into functions
{
Component: () => (
<ComponentA />
),
},
// And then call it in the map()
{allComponents(false).map(c => (
c.Component()
))}
or return the JSX from an IIFE inside the map()
call
{allComponents(false).map(c => (
(() => c.Component)()
))}
Working snippet
const App = () => {
const allComponents = isValid => [
{
Component: (
<ComponentA />
)
,
},
{
Component: (
<div>
{<ComponentB />}
</div>
)
,
},
!isValid && {
Component: (
<div>
{<ComponentC />}
</div>)
,
},
].filter(Boolean);
return (
<div>
<p>isValid: False</p>
<div>
{allComponents(false).map(c => (
(() => c.Component)()
))}
</div>
<p>isValid: True</p>
<div>
{allComponents(true).map(c => (
(() => c.Component)()
))}
</div>
</div>
);
}
const ComponentA = () => {
return (
<div>Component A</div>
)
}
const ComponentB = () => {
return (
<div>Component B</div>
)
}
const ComponentC = () => {
return (
<div>Component C</div>
)
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 1
Reputation: 2562
return (
<Fragment>
{allComponents(false).map(c => (
{c.component}
))}
</Fragment>
);
you are attempting to render an object in your above example and not the component itself. IMO I would update your overall structure
Upvotes: 0