Search code examples
reactjsgatsbygatsby-imagegatsby-plugin

gatsby-plugin-image Load image with the given prop


Consider I have the following component

// variant can be one of [facebook, google, apple, ...etc]
<CompanyLogo variant="facebook"/>

The number of possible values of variant is finite.

I would like to dynamically load the corresponding image depending on the value of the variant prop.

Now, I have thought of 2 ways to do it.

Option 1: Query all company logo images using GraphQL and find the one I need using JS.

const { images: { edges: images } } = useStaticQuery(graphql`
    query {
      images: allFile(filter: {
        sourceInstanceName: {eq: "images"}, 
        relativeDirectory: {eq: "companies"}
      }) {
        edges {
          node {
            name
            childImageSharp {
              gatsbyImageData
            }
          }
        }
      }
    }
  `);

const image = images.find(({ node: { name } }) => variant === name );

The concern I have is that I'm not sure whether this will greatly impact performance, especially when there are many company logos.

Option 2: Use switch or if condition to load the images

switch (variant) {
  case 'facebook':
    return <StaticImage src="facebook.png" />
  case 'apple':
    return <StaticImage src="apple.png" />
  // ...etc
}

The issue is the code is really smelly.

Do you have a better way to achieve that?


Solution

  • Among the two approaches, option 1 is the best approach for you.

    Keep in mind that in a switch/case approach you will be evaluating all cases until your option is matched, like if you had a bunch of ifs. Option 2 is the lowest performance approach.

    I would add a third trial, which in my opinion is the most performant, a dictionary (map):

    const LOGO_VARIANTS = {
     facebook: <StaticImage src="facebook.png" />,
     apple: <StaticImage src="apple.png" />,
     potatoes: <StaticImage src="potatoes.png" />,
     'dashed-logo':  <StaticImage src="dashed-logo.png" />
    }
    

    Then, you only need to access the position with the key-value like:

    const SomeComponent = () =>{
    
       return <div>My logo is {LOGO_VARIANTS['facebook']}</div>
    }
    

    Note: tweak that logic to adapt it to your needs, like assigning the LOGO_VARIANTS['facebook'] to a new variable and render it like: const Image= LOGO_VARIANTS['facebook'] and then <Image/>

    I'm not sure about the whole logic and this approach may not be the best/optimal solution for you. If you don't want to overkill the logic, I would use the option 1 which is far better than the 2.