Search code examples
javascriptreactjsjsxreact-props

How to add additional component as prop to a reusable component in React?


I have a simple card component which takes a title and description as props. I wanted to reuse the component but this time I only want to add a button the component without changing the original component.

For example, below is the card component.

export const SimpleCard = React.memo(function SimpleCard({
  title,
  description,
}) {
  const styles = useStyles();
  const shadowStyles = useOverShadowStyles();
  return (
    <Card className={cx(styles.root, shadowStyles.root)}>
      <CardContent>
        <Typography variant="h5" align="center" style={{ fontWeight: "bold" }}>
          {title}
        </Typography>
        <Typography variant="subtitle1" align="center">
          {description}
        </Typography>
      </CardContent>
    </Card>
  );
});

export default SimpleCard;

So now, I want to import the <SimpleCard/> component and just pass the a new button component as a prop. I'm using the card component in other places so I need to have this original component without the button component. I know I can make another separate Card with button component or just pass an empty prop to the Card component with button but I want to know if it's possible to access the original Card component and add the button component as props.

I imagine it would be something like this.

<SimpleCard
          title={"Just shoot us an inquiry about your dream app or website!"}
          description={`Send us more details and we can discuss further`}
          How to pass the <Button/> component from here?
        />

Solution

  • You can use the children prop and put your content as the content of your JSX as in the following example:

    <SimpleCard>
      <span>this is the children</span>
    </SimpleCard>
    

    To use the children in your component you have to refer to it as the children prop:

    export const SimpleCard = React.memo(function SimpleCard({
      title,
      description,
      children,
    }) {
      const styles = useStyles();
      const shadowStyles = useOverShadowStyles();
      return (
        <Card className={cx(styles.root, shadowStyles.root)}>
          <CardContent>
            <Typography variant="h5" align="center" style={{ fontWeight: "bold" }}>
              {title}
            </Typography>
            <Typography variant="subtitle1" align="center">
              {description}
            </Typography>
            {children}
          </CardContent>
        </Card>
      );
    });
    
    export default SimpleCard;
    

    Then the children prop will be basically replaced with <span>this is the children</span> or whatever toy want.

    Another way is to pass your custom content as a custom prop like in the following example:

    <SimpleCard customContent={<span>this is the children</span>} />
    

    And then, as usual:

    export const SimpleCard = React.memo(function SimpleCard({
      title,
      description,
      customContent,
    }) {
      const styles = useStyles();
      const shadowStyles = useOverShadowStyles();
      return (
        <Card className={cx(styles.root, shadowStyles.root)}>
          <CardContent>
            <Typography variant="h5" align="center" style={{ fontWeight: "bold" }}>
              {title}
            </Typography>
            <Typography variant="subtitle1" align="center">
              {description}
            </Typography>
            {customContent}
          </CardContent>
        </Card>
      );
    });
    
    export default SimpleCard;