Trouble displaying additional images on button click in React Gallery component

48 views Asked by At

I have a React Gallery component that initially displays a set number of images. When a button is clicked, I want the component to show additional images. However, my current implementation is not working as expected. The code is provided below:

import React, { useState } from 'react';
import GridElem1 from '../assets/img/App/gallery/grid-row-1.jpg'
import GridElem2 from '../assets/img/App/gallery/grid-col-1.jpg'
import GridElem3 from '../assets/img/App/gallery/grid-row-2.jpg'
import GridElem4 from '../assets/img/App/gallery/grid-col-2.jpg'
import GridElem5 from '../assets/img/App/gallery/grid-col-3.jpg'
import GridElem6 from '../assets/img/App/gallery/grid-row-3.jpg'
import GridElem7 from '../assets/img/App/gallery/grid-row-4.jpg'
import GridElem8 from '../assets/img/App/gallery/grid-col-4.jpg'
import GridElem9 from '../assets/img/App/gallery/grid-col-5.jpg'
import GridElem10 from '../assets/img/App/gallery/grid-row-5.jpg'
import GridElem11 from '../assets/img/App/gallery/grid-row-6.jpg'
import GridElem12 from '../assets/img/App/gallery/grid-col-6.jpg'
import {
    MDBCol,
    MDBRow,
} from 'mdb-react-ui-kit';

const Gallery = () => {
    const allImages = [GridElem1, GridElem2, GridElem3, GridElem4, GridElem5, GridElem6, GridElem7, GridElem8, GridElem9, GridElem10, GridElem11, GridElem12]
    const imagesPerPage = 1;
    const [visibleImages, setVisibleImages] = useState(allImages.slice(0, imagesPerPage));
    const showMoreImages = () => {
        const currentVisibleCount = visibleImages.length;
        const newVisibleImages = allImages.slice(currentVisibleCount, currentVisibleCount + imagesPerPage);
        const uniqueNewVisibleImages = newVisibleImages.filter(img => !visibleImages.includes(img));
        setVisibleImages((prevVisibleImages) => [...prevVisibleImages, ...uniqueNewVisibleImages]);
    }
    // console.log(visibleImages);
    // visibleImages.map((img, index) => {
    //     console.log(allImages[index]);
    // })

    return (
        <>
            {visibleImages.map((image, index) => (
                <MDBRow key={index}>
                    <MDBCol lg={4} md={12} className='mb-4 mb-lg-0'>
                        <img
                            src={image}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 1}`} />

                        <img
                            src={allImages[index * 2 + 1]}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 2}`} />
                    </MDBCol>

                    <MDBCol lg={4} className='mb-4 mb-lg-0'>
                        <img
                            src={allImages[index * 2 + 2]}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 3}`} />

                        <img
                            src={allImages[index * 2 + 3]}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 4}`} />
                    </MDBCol>

                    <MDBCol lg={4} className='mb-4 mb-lg-0'>
                        <img
                            src={allImages[index * 2 + 4]}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 5}`} />

                        <img
                            src={allImages[index * 2 + 5]}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 6}`} />
                    </MDBCol>
                </MDBRow>

            ))}
            {visibleImages.length < allImages.length && (
                <button onClick={showMoreImages}>Показать еще</button>
            )}
        </>
    );
}

export default Gallery;

I attempted to implement a "show more" functionality in the Gallery component. However, the additional images are not being displayed correctly. I expected that clicking the "Show More" button would append more images to the existing ones.

1

There are 1 answers

0
Ihor On

I'm not quite sure if it's a reason but there is an unnecessary filtering for unique images: The line that filters for unique images may not be necessary. Since you are slicing the allImages array based on the count of currently visible images, the new images you're adding should already be unique and not present in the visibleImages array. This line can be removed to simplify the code:

const uniqueNewVisibleImages = newVisibleImages.filter(img => !visibleImages.includes(img));

You can directly use newVisibleImages in the setVisibleImages call.

Another possible option: have you tried to implement your logic without that grid (mdbcols and rows)? I think the problem is in keys that must be used for images and not for grid rows because you slice an array of images and then render them out. I guess you could try something like this:

const Gallery = () => {
const allImages = [GridElem1, GridElem2, GridElem3, GridElem4, GridElem5, GridElem6, GridElem7, GridElem8, GridElem9, GridElem10, GridElem11, GridElem12];
const imagesPerPage = 1;
const [visibleImages, setVisibleImages] = useState(allImages.slice(0, imagesPerPage));

const showMoreImages = () => {
    const currentVisibleCount = visibleImages.length;
    const newVisibleImages = allImages.slice(currentVisibleCount, currentVisibleCount + imagesPerPage);
    setVisibleImages(prevVisibleImages => [...prevVisibleImages, ...newVisibleImages]);
};

return (
    <div>
        {visibleImages.map((ImageComponent, index) => (
            <ImageComponent key={index} />
        ))}
        <button onClick={showMoreImages}>Next slide</button>
    </div>
)};