I have a react app. In the app on one page I am rendering images on the page, all images are different. To do this I am mapping over the images. When you click on an image, a modal appears with a larger version of the image, except all the images are the same image (which is the last image in my array). Why??
Here is the code:
import React, { useState } from 'react';
/* Components */
import { Button, Modal } from 'react-bootstrap';
const myComponent = () => {
// controls for image modals
const [showImageModal, setShowImageModal] = useState(false);
const handleCloseImageModal = () => setShowImageModal(false);
const handleShowImageModal = () => setShowImageModal(true);
const imageURLs = {code to read images from directory goes here. This is working!}
return (
<>
{imageURLs.map((url) => (
<>
{/* The follow line works! Images are rendered correctly on the screen */}
<Button className='modalButton' onClick={handleShowImageModal}><img src={require(`../../uploadedImages/${url}`).default} className='imageCards'></img></Button>
{/* The following lines render a modal but all modal images are the same */}
<Modal show={showImageModal} onHide={handleCloseImageModal}>
<img src={require(`../../uploadedImages/${url}`).default}></img>
</Modal>
</>
))}
</>
)
}
export default myComponent;
Just to give an idea of the results, the images on the component render correctly:
But when clicking to see a modal, they all are the same image:
The modals are correct, you're just showing all five of them at the same time. Consider the state value(s) you're tracking. You have five modals, but only one boolean value indicating if those modals are shown/hidden:
const [showImageModal, setShowImageModal] = useState(false);
So either all of them are shown or all of them are hidden. Instead, track which modal you want to show or hide. You could do this by tracking a unique identifier for them instead of just a boolean value. For example, if url
is the unique identifier:
// default to undefined so they're all hidden
const [showImageModal, setShowImageModal] = useState();
Then update to the url
of the modal clicked on:
const handleShowImageModal = (url) => setShowImageModal(url);
Which you'd pass to the function:
<Button className='modalButton' onClick={() => handleShowImageModal(url)}>
And the modal itself would show if the state value matches its url
:
<Modal show={showImageModal === url} onHide={handleCloseImageModal}>
Then hiding them would just be a matter of setting the value back to undefined
:
const handleCloseImageModal = () => setShowImageModal(undefined);