K.Kröger
K.Kröger

Reputation: 95

Set props to Component coming from an Object

I'm trying to chain a React Components to Object by passing my imported Components to them as Props.

const [showComponent, setShowComponent] = useState([
    { cId: 1, componentName: <ContactDialogAddresses />, title: 'Adresse', render: true },
    { cId: 2, componentName: <ContactDialogPhone />, title: 'Rufnummer', render: true },
]);

return(
    {showComponent.map((component, index) => {
        if (component.render) {
            return (
                <>
                    <span>{index}</span>
                    {component.componentName}
                </>
            );
        }
    })}
)

How can I reimplement props like this?

// I need to pass the props during the mapping because I need a unique identifier for each rendert component later on.

 <ContactDialogAddresses
   key={component.cId}
   onShowComponent={handleShowComponent}
   cIndex={index}
 />

Upvotes: 0

Views: 51

Answers (1)

Nikita Chayka
Nikita Chayka

Reputation: 2137

One of the options would be to do component creators/renderers (basically functions) in your state, rather than directly components.

Something like this:

const [showComponent, setShowComponent] = useState([
   { cId: 1, componentRenderer: (props) => { return (<ContactDialogAddresses {...props} />)}, title: 'Adresse', render: true },
   { cId: 2, componentRenderer: (props) => { return (<ContactDialogPhone {...props} />) }, title: 'Rufnummer', render: true },
]);

return(
    {showComponent.map((component, index) => {
        if (component.render) {
            return (
                <>
                    <span>{index}</span>
                    {component.componentRenderer({someProp:'someValue'})}
                </>
            );
        }
    })}
)

Another option could be using variables - important they should be capitalized (and do not do < /> in componentName in your state):

const [showComponent, setShowComponent] = useState([
   { cId: 1, componentName: ContactDialogAddresses, title: 'Adresse', render: true },
   { cId: 2, componentName: ContactDialogPhone, title: 'Rufnummer', render: true },
]);

return(
    {showComponent.map((component, index) => {
        if (component.render) {
            const TargetComponent = component.componentName
            return (
                <>
                    <span>{index}</span>
                    <TargetComponent x="y"/>
                </>
            );
        }
    })}
)

Otherwise you could use createElement - https://reactjs.org/docs/react-api.html#createelement

Actually there is good thread here - React / JSX Dynamic Component Name with some good discussions there, so kudos goes there

Upvotes: 2

Related Questions