Element type invalid

I am trying to loop out some partner logos from a headless CMS, but whenever I try to use React-components in my file I get an error stating

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `Partners`.

I can use my map functions as pure javascript functions but when I try to use them as React components I get this error.

What I want to work

  const SinglePartner = ({partner}) => {
    return (
      <Col sm="6" md="3" lg="4" className="logoScaling">
        <h4 className="text-center">{partner.title}</h4>
        <img
          src={partner.partnerLogo.asset.url}
          alt={partner.partnerLogo.alt}
          className="partnerLogos"
        />
      </Col>
    )   }

  const PartnerLooper = partners.map((partner) => {
    return <SinglePartner key={partner._key} />    })

When debugging I tried simplifying my components, re-writing my PartnerLooper to

  const PartnerLooper = partners.map((partner) => {
    return <p>{partner.name}</p>
  })

Using this method I can call PartnerLooper as a javascript function but not as a react component

return(
          {/* Returns errror */}
         <PartnerLooper />
         {/* Works  */}
         {PartnerLooper}
)

Full component code:

import React from "react";
import { Col, Row } from "react-bootstrap";


const Partners = ({ partners }) => {
  
  const PartnerLooper = partners.map((partner) => {
    return <SinglePartner partner={partner} /> 
  })

  const SinglePartner = ({partner}) => {
    return (
      <Col sm="6" md="3" lg="4" className="logoScaling">
        <h4 className="text-center">{partner.title}</h4>
        <img
          src={partner.partnerLogo.asset.url}
          alt={partner.partnerLogo.alt}
          className="partnerLogos"
        />
      </Col>
    )
  }
  return (
    <div className="container pt-8 pt-md-10 partnerPadding" role="region">
      <section aria-label="Partners">
        <Row className="justify-content-md-center">
         <PartnerLooper />
        </Row>
      </section>
    </div>
  );
};

export default Partners;

See the datastructure I am working with here
https://pastebin.com/MFGh1xuY

EDIT: I am running "gatsby": "^2.22.15" and "react": "^16.12.0",

3 thoughts on “Element type invalid”

  1. Thank you DustInCompetent, your answer helped me

    I did not want to run map directly in JSX because I think it is a bit ugly, I solved this by wrapping my SinglePartner and PartnerLooper-components in a parent component and using the return from this component. Full code:

    const Partners = ({ partners }) => {
    
      const AllPartners = () => {
        const SinglePartner = ({ partner }) => {
          return (
            <Col sm="6" md="3" lg="4" className="logoScaling">
              <h4 className="text-center">{partner.title}</h4>
              <img
                src={partner.partnerLogo.asset.url}
                alt={partner.partnerLogo.alt}
                className="partnerLogos"
              />
            </Col>
          )
        }
        const PartnerLooper = partners.map((partner) => {
          return <SinglePartner partner={partner} />
        })
        return PartnerLooper
      }
    
    
      return (
        <div className="container pt-8 pt-md-10 partnerPadding" role="region">
          <section aria-label="Partners">
            <Row className="justify-content-md-center">
              <AllPartners />
            </Row>
          </section>
        </div>
      );
    };
    
    export default Partners;
    
    Reply
  2. You’re assigning an array of elements to PartnerLooper and then using it as a component <PartnerLooper/> in the Partners component. you can insert an element array directly as a child in JSX.

    Replace the returned JSX with

    <div className="container pt-8 pt-md-10 partnerPadding" role="region">
      <section aria-label="Partners">
        <Row className="justify-content-md-center">
          {PartnerLooper} 
        </Row>
      </section>
    </div>
    

    If you meant to render one Row per partner, <ou can achieve that like this:

    return (
      <div className="container pt-8 pt-md-10 partnerPadding" role="region">
        <section aria-label="Partners">
          {partners.map(partner =>
            <Row className="justify-content-md-center" key={partner._key}>
              <SinglePartner partner={partner} /> 
            </Row>
          )}
        </section>
      </div>
    ) 
    
    Reply

Leave a Comment