skip to Main Content

So I have an array of objects that look like this:

export const serviceList = [
  {
    title: "Exterior Services",
    image: "/images/service-card-images/kendall-painting.webp",
    description: "ExteriorServicesDescription",
    id: 1,
    link: "/services/painting",
  },

I am mapping this list to a card component where the info is displayed. I decided I wanted some more complex jsx to display in the description than just a text blurb, (basically some p tags and a list), so I made a small component to display, for example <ExteriorServicesDescription />. How can I pass this component, or a reference to this component, into the one rendering the information?

I have tried typing description as a React.ReactNode and just passing the component as <ExteriorServicesDescription /> but linting only saw it as a type, and I also tried passing the name of the component as a string and then like this in the component:

{serviceList.map((service) => (
          <ServiceCard
            key={service.id}
            title={service.title}
            image={service.image}
            description={<service.description />}
            link={service.link}
          />
        ))}

but nothing renders to the page shows as <exteriorservicesdescription></exteriorservicesdescription>.

Here is the <ServiceCard /> component:

import React from "react";
import ExteriorServicesDescription from "./ExteriorServicesDescription";
import Image from "next/image";


interface ServiceCardProps {
  title: string;
  image: string;
  description: React.ReactNode;
  link: string;
}

const ServiceCard = ({ title, image, description, link }: ServiceCardProps) => {
  return (
    <div className="w-4/5 flex flex-col items-center m-auto justify-center no-underline border-2 rounded-2xl shadow-black shadow border-black">
      <div className="w-full h-64 relative">
        <Image
          src={image}
          alt={title}
          fill={true}
          className="rounded-t-xl"
        />
      </div>
      <h2 className="text-xl no-underline bg-black text-gold w-full text-center py-2">
        {title}
      </h2>
      {description}
      <a
        href={link}
        className="text-lg border rounded-2xl border-black px-2 py-1 mb-2 hover:bg-slate-300 hover:scale-105 transition-all duration-100"
      >
        Learn More
      </a>
    </div>
  );
};

export default ServiceCard;

Any ideas?

2

Answers


  1. "ExteriorServicesDescription" is a string in your case, it cannot behave like a react component.

    If you have a react component named ExteriorServicesDescription, you should pass it directly as a value of description in serviceList.

    export const serviceList = [
      {
        title: "Exterior Services",
        image: "/images/service-card-images/kendall-painting.webp",
        description: ExteriorServicesDescription, // The real component
        id: 1,
        link: "/services/painting",
      },
    
    Login or Signup to reply.
  2. To render a specific component is responsibility of the React app, not of the API.

    Just send a string and use an if/switch statement inside your component:

    enum DescriptionTypes {
      Exterior,
      Interior,
    };
    
    interface ServiceCardProps {
      title: string;
      image: string;
      description: DescriptionTypes;
      link: string;
    }
    
    const ServiceCard = ({ title, image, description, link }: ServiceCardProps) => {
      function renderDescription() {
        if (description === DescriptionTypes.Exterior) {
          return <ExteriorServicesDescription/>
        }
        if (description === DescriptionTypes.Interior) {
          return <InteriorServicesDescription/>
        }
      }
    
      return (
        <div className="...">
          ...
          {renderDescription()}
          ...
        </div>
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search