Search code examples
graphqlcarouselgatsbyreact-bootstrapgatsby-image

gatsby-sharp images loaded via graphql in react-carousel not activated


I have created a react-bootstrap carousel with some images I load via graphql and gatsby-image-sharp (the source images are in directus).

I see the images are created in the code, but they never get assigned the "active" class. When I put the images outside of the carousel, they are shown correctly one below the other, so the retrieval seems to work fine.

If I manually add an item before and/or after the graphql images, those slides get shown correctly.

I also see that in case I put a slide before and after the graphql ones, the first "normal" slide gets shown and when the transaction is started, I get a delay corresponding to the number of generated slides before the next statically created slide is shown again.

When inspecting the site with the react development tools, I see the working slides have a transaction key of ".0" and ".2", while the non-working slides between them have transaction keys of ".1:0:0", ".1:0:1", etc...:

React devtools tree

The code I use to generate this is included below:

import React from "react"
import { Row, Col, Container, Carousel } from "react-bootstrap"
import { graphql } from "gatsby"

import Layout from "../components/layout"
import SEO from "../components/seo"
import Img from "gatsby-image"

const IndexPage = ({ data }) => (
  <Layout pageInfo={{ pageName: `index` }}>
    <SEO title="Home" keywords={[`gatsby`, `react`, `bootstrap`]} />
    <Container className="text-center">
      <Row>
        <Col>
          <Carousel>
            <Carousel.Item>
              <div className="d-block w-100 gatsby-image-wrapper">
              <h1>test</h1>
              </div>
            </Carousel.Item>
            {data.allDirectusSlideshow.edges.map((slideShow) => {
              return slideShow.node.images.map((image) => {
                const sharp = data.allImageSharp.edges.find((imageSharp) => (
                  imageSharp.node.fluid.originalName === image.filename_disk))
                return <>
                  <Carousel.Item key={sharp.node.id}>
                    <h1>Image</h1>
                    <Img fluid={sharp.node.fluid} className="d-block w-100" />
                  </Carousel.Item>
                </>
              })
            })}
            <Carousel.Item>
              <h1>Test 2</h1>
            </Carousel.Item>
          </Carousel>
        </Col>
      </Row>
    </Container>
  </Layout>
)

export const query = graphql`
    query {
      allDirectusSlideshow(filter: {title: {eq: "Voorpagina"}}) {
        edges {
          node {
            title
            images {
              filename_disk
            }
          }
        }
      }
      allImageSharp {
        edges {
          node {
            id
            fluid {
              originalName
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
  `
export default IndexPage

As the directus api for this site is not public, I have put up a generated code example here (note: only the homepage works)


Solution

  • Apparently, bootstrap carousel expects its items to be a direct child of the carousel. This means that react fragments don't work over here.

    Changing this:

      return <>
                  <Carousel.Item key={sharp.node.id}>
                    <h1>Image</h1>
                    <Img fluid={sharp.node.fluid} className="d-block w-100" />
                  </Carousel.Item>
                </>
    

    To this solves the issue:

      return (
                      <Carousel.Item key={sharp.node.id}>
                        <h1>Image</h1>
                        <Img fluid={sharp.node.fluid} className="d-block w-100" />
                      </Carousel.Item>
                    )