Search code examples
reactjscarouselreact-bootstrap

Moving Carousel Item to a different class doesn't work [React]


EDIT: CodeSandBox link - https://codesandbox.io/s/lucid-boyd-9tqhg?file=/src/HomeCarousels.js

The following code works fine:

            <Carousel>
                <Carousel.Item>
                    <img
                    className="d-block w-100"
                    src="https://www.fg-a.com/wallpapers/2019-black-fantasy-sky.jpg"
                    alt="Second slide"
                    />
                    <Carousel.Caption>
                    <h3>Second slide label</h3>
                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
                    </Carousel.Caption>
                </Carousel.Item>

                <Carousel.Item>
                    <img
                    className="d-block w-100"
                    src="https://www.fg-a.com/wallpapers/black-circles-2018.jpg"
                    alt="Third slide"
                    />
                    <Carousel.Caption>
                    <h3>Third slide label</h3>
                    <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur.</p>
                    </Carousel.Caption>
                </Carousel.Item>
            </Carousel>

However, when I try to refactor it by moving a single Carousel.Item into its own React Component, I run into issues.

SingleCarousel.js

class SingleCarousel extends React.Component {

    render() {
        return (
            <Carousel.Item>
                <img
                    className="d-block w-100"
                    src={this.props.imgPath}
                    alt={this.props.header}
                />
                <Carousel.Caption>
                    <h3>{this.props.header}</h3>
                    <p>{this.props.content}</p>
                </Carousel.Caption>
            </Carousel.Item>
        );
    }

}

Main.js (currently just replacing one carousel with an instance of class):

            <Carousel>
                <SingleCarousel
                    imgPath="https://www.fg-a.com/wallpapers/2019-black-fantasy-sky.jpg"
                    header="Second slide label"
                    content="Lorem ipsum dolor sit amet, consectetur adipiscing elit."
                />

                <Carousel.Item>
                    <img
                    className="d-block w-100"
                    src="https://www.fg-a.com/wallpapers/black-circles-2018.jpg"
                    alt="Third slide"
                    />
                    <Carousel.Caption>
                    <h3>Third slide label</h3>
                    <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur.</p>
                    </Carousel.Caption>
                </Carousel.Item>
            </Carousel>

In the second case, the first carousel item does not render on the page. However, I can see the DOM element present in the DOM tree. On inspecting in chrome, the issue is that "carousel-item" div for the first item never changes to "active carousel-item". I actually have more than two elements, so I can see that it is cycling through all items, but unable to convert the Component item to active, hence it doesn't render. Why am I experiencing this behaviour? Aren't the two pieces of code equivalent, and should produce identical behaviour?


Solution

  • I thought that both codes are equivalent but it's not, so one of the answers is to replace Carousel.Item to Fragment in your SingleCarousel and call it as

    <Carousel.Item>
      <SingleCarousel
        imgPath="https://www.fg-a.com/wallpapers/black-with-stars.jpg"
        header="First slide label"
        content="Placeholder text"
      />
    </Carousel.Item>    
    

    Carousel.Item is required for transition, so you need to add that before calling something

    Codesandbox: https://codesandbox.io/s/purple-wave-3300o?file=/src/HomeCarousels.js