React components losing styling on rerender

Viewed 43

I'm using @egjs/react-infinitegrid (https://naver.github.io/egjs-infinitegrid/) to create a Masonry grid of image components to form a gallery on my GatsbyJS website. I would like to be able to show a lightbox containing a full screen image when one of the images in the gallery is clicked.

I am running into an issue where when I show/hide a component using selective rendering, all of the <div> components within the gallery lose their styling when a component is shown/hidden. This means that the grid breaks and I am left with just a long column of images. I have tested this also with just showing/hiding a <p> component on the page and experience the same behaviour.

Please see the video of the behaviour below. Notice that when I click my 'Test' button, and the 'Hello!' component is shown, all of the <div> components containing the images lose their position styling (you can see this update in the chrome developer view on the right).

Video: https://imgur.com/a/3PpYr6Z

Before: enter image description here

After: enter image description here

Can anyone see what may be happening here? My code is below:

Page.tsx:

import React, { useState } from "react";
import { graphql, useStaticQuery } from "gatsby";
import GalleryComp from "../../components/gallery";
import Lightbox from "../../components/Lightbox";

export default function Lighting() {
    const [showLightbox, setShowLightbox] = useState(false);
    const [selectedImage, setSelectedImage] = useState(null);

    const query = useStaticQuery(graphql`
        query galleryQuery {
            allFile(filter: { absolutePath: { regex: "/images/test/" } }) {
                edges {
                    node {
                        childImageSharp {
                            gatsbyImageData(
                                placeholder: BLURRED
                                transformOptions: { fit: OUTSIDE }
                                width: 250
                            )
                            resize {
                                aspectRatio
                            }
                            fluid {
                                src
                            }
                        }
                        publicURL
                    }
                }
            }
        }
    `);

    return (
    <>
        <div className="mt-64">
            <div className="flex flex-col items-center justify-center mb-10">
                <button onClick={() => setShowLightbox(true)} className="text-white border-2 border-white rounded-xl p-2">Test</button>
                {showLightbox ? (
                    <p className="text-white">Hello!</p>
                ) : null}
            </div>
                
            <GalleryComp query={query} />
    </>
    );
}

Gallery.tsx:

import { GatsbyImage, getImage } from "gatsby-plugin-image";
import React, { useRef } from "react";
import { MasonryInfiniteGrid } from "@egjs/react-infinitegrid";
import { useEffect } from "react";

export default function GalleryComp(props: any) {
    const data = props.query;
    const images = data.allFile.edges.map(
        ({ node }) => node.childImageSharp.gatsbyImageData
    );

    const igRef = useRef();

    function getItems(nextGroupKey: number, count: number) {
        const nextItems = [];
        const nextKey = nextGroupKey * count;

        for (let i = 0; i < count; ++i) {
            nextItems.push({ groupKey: nextGroupKey, key: nextKey + i });
        }
        return nextItems;
    }

    const numPics = data.allFile.edges.length;
    console.log(numPics);
    const [items, setItems] = React.useState(() => getItems(0, numPics));

    const Item = ({ num }: any) => (
        <div
            className="item h-auto"
            style={{
                width: "250px",
            }}
        >
            <div className="thumbnail">
                <GatsbyImage
                    image={getImage(images[num])}
                    alt={"blah"}
                    className="rounded-xl shadow-xl"
                    imgStyle={{ objectFit: "contain" }}
                />
            </div>
        </div>
    );

    return (
        <>
            <MasonryInfiniteGrid
                className="container"
                gap={5}
                ref={igRef}
                onRequestAppend={(e) => {
                    const nextGroupKey = (+e.groupKey! || 0) + 1;
                    setItems([...items, ...getItems(nextGroupKey, numPics)]);
                }}
            >
                {items.map((item) => (
                    <Item
                        data-grid-groupkey={item.groupKey}
                        key={item.key}
                        num={item.key}
                    />
                ))}
            </MasonryInfiniteGrid>
        </>
    );
}

Thanks!

0 Answers
Related