So I have an array of images, which I would like to hide or show on a click of a button. right now when I try to hide the image, it will hide the entire array.
import "./main.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useEffect, useState } from "react";
import {
faCircleChevronLeft,
faCircleChevronRight,
faCircleXmark,
} from "@fortawesome/free-solid-svg-icons";
const Main = ({ galleryImages }) => {
const [slideNumber, setSlideNumber] = useState(0);
const [openModal, setOpenModal] = useState(false);
const [pics, setPics] = useState([]);
const [show, toggleShow] = useState(true);
// buttons next to name of diff charts (hide/show chart)
const handleOpenModal = (index) => {
setSlideNumber(index);
setOpenModal(true);
};
const removeImage = (id) => {
setPics((oldState) => oldState.filter((item) => item.id !== id));
};
// const hide = () => {
// setShow(false)
// }
const handleCloseModal = () => {
setOpenModal(false)
}
useEffect(()=> {
setPics(galleryImages)
},[]);
return (
<div>
<button onClick={() => toggleShow(!show)}>toggle: {show ? 'show' : 'hide'}</button>
{show &&
<div>
{pics.map((pic) => {
return (
<div style = {{marginBottom:'100px'}}>
{pic.id}
<img
src={pic.img}
width='500px'
height='500px'
/>
<button onClick ={() => removeImage(pic.id)}>Delete</button>
</div>
)
})}
</div>
I tried making a state component to try to hide and show the images, however it will hide the entire array instead of the individual image
CodePudding user response:
i would add a show var to the galleryImages array and then set it so you get control of each image like this
import { useState } from "react";
import { v4 as uuidv4 } from "uuid";
import "./main.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useEffect, useState } from "react";
import {
faCircleChevronLeft,
faCircleChevronRight,
faCircleXmark,
} from "@fortawesome/free-solid-svg-icons";
function Main({ galleryImages }) {
const [slideNumber, setSlideNumber] = useState(0);
const [openModal, setOpenModal] = useState(false);
const [pics, setPics] = useState([]);
// buttons next to name of diff charts (hide/show chart)
const toggleShow = ({ id, show }) => {
setPics((oldState) =>
oldState.map((item) => {
if (item.id !== id) return item;
return { ...item, show: !show };
})
);
};
const removeImage = (id) => {
setPics((oldState) => oldState.filter((item) => item.id !== id));
};
useEffect(() => {
setPics(
galleryImages.map((galleryImage) => {
return { ...galleryImage, show: true };
})
);
}, []);
return (
<div>
<div>
{pics.map((pic) => {
return (
<>
<button
onClick={() => toggleShow({ show: pic.show, id: pic.id })}
>
toggle: {pic.show ? "show" : "hide"}
</button>
{pic.show && (
<div style={{ marginBottom: "100px" }}>
{pic.id}
<img src={pic.img} width="500px" height="500px" />
<button onClick={() => removeImage(pic.id)}>Delete</button>
</div>
)}
</>
);
})}
</div>
</div>
);
}
export default Main;
`
CodePudding user response:
If you would like the option to hide individual pics, to accomplish this you are correct in your state component approach. First you can create a pic component that has its own state with a hide/show button:
export default function Pic({pic}) {
const [showPic, setShowPic] = useState(true);
const handleClick = () => {setShowPic(!showPic)}
return (
<div>
<div style={showPic ? {display : "block"} : {display : "none"}}>
<img
src={pic.img}
width='500px'
height='500px'
/>
</div>
<button onClick={handleClick}>{showPic ? 'Hide' : 'Show'}</button>
</div>
)
}
Next, you can import this component into your main file
import Pic from 'location/Pic.js';
and map each pic to a <Pic>
component.
{pics.map((pic) => <Pic pic={pic} key={pic.id}/>)}
Now the images will be shown each with their own Hide/Show button that can toggle their display with the state contained within each <Pic/>
component. This is good practice because toggling one image will not cause a re-render of the entire image gallery.