How to pass component constructor in React props?
I'm a beginner for React. So below example may make it clear what I am trying to achieve.
Example:
PorkComponent:
const PorkComponent = ({ children, variant }: PorkComponentProps) => {
return (
<motion.div>
...
</motion.div>
);
};
DuckComponent:
const DuckComponent = ({ children, variant }: DuckComponentProps) => {
return (
<motion.div>
...
</motion.div>
);
};
The Lunch
component will contains PorkComponent
or DuckComponent
Based on LunchProps.meatType.
type LunchProps = {
meatType: React.ComponentType;
};
const Lunch = (props: LunchProps) => {
return (
<props.meatType> // Here it will return PorkComponent or DuckComponent based on what props.meatType.
);
}
Sure I can use something like:
const Lunch = (props: LunchProps) => {
return (
if (props.isPork) {
< PorkComponent >
} else(props.isDuck) {
< DuckComponent >
}
....
);
}
But I don't want to have multiple IFELSE check in Lunch
component. Instead, I want the caller to specify the "meat type", like <Lunch meatType= PorkComponent>
.
CodePudding user response:
I recently saw this someone shared on Twitter,
const MeatComponents = {
'pork': <PorkComponent />
'duck': <DuckComponent />
}
const Lunch = (props) => {
return MeatComponent[props.meatType]
}
// usage
<Lunch meatType='pork' />
<Lunch meatType='duck' />
Or you could just use,
const Lunch = ({ children }) => {
return <>{children}</>
}
// usage
<Lunch>
<PorkComponent />
</Lunch>
CodePudding user response:
You can simply write :
const Lunch = (props: LunchProps) => <props.meatType />;
<Lunch meatType={DuckComponent} />
Here is an example on stackblitz
CodePudding user response:
You can pass the rendered component directly instead:
// in Lunch component
return (<div>{props.meatType}</div>);
<Lunch meatType={<PorkComponent />} />
If you just want to return the given component, simply use:
return props.meatType;
CodePudding user response:
you can pass component functions as props. You almost got the answer.
const Lunch = (props) => {
return (
// React.createElement(props.meatType, {}, null)
<props.meatType /> // this is valid, I have tested before replying.
);
}
// then
<Lunch meatType={PorkComponent} />
// or
<Lunch meatType={DuckComponent} />
// even this works and renders a div
<Lunch meatType="div" />