Call component on button click or make multiple useStates?


I’m currently trying to make an image gallery using react and bootstrap.

ignoring the actual content and syntax, this is kind of what the code looks like. I want a total of 6 images that are side by side in a 3×2 grid. Each image has a onHover where itll show a black transparent background with some text.

function Projects() {
  const [show, setShow] = useState(false);
  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);
  const [show1, setShow1] = useState(false);
  const handleClose1 = () => setShow1(false);
  const handleShow1 = () => setShow1(true);
  const [show1, setShow2] = useState(false);
  const handleClose2 = () => setShow2(false);
  const handleShow2 = () => setShow2(true);
  x3 more times

  return (
              <div class="img__wrap"> // this is just the first image
                <img class="projectCard" src={test} />
                <div class="img__description_layer">
                  <p class="img__description">some text.</p>
                  <button onClick={handleShow}>test</button>
                  <Modal show={show} onHide={handleClose}>
                    <Modal.Header className="background" closeButton>
                      <Modal.Title className="smallerProjectHeadings">title</Modal.Title>
                    <Modal.Body className="background">
                      <Image className='projectImg' src={image} alt='Oneshot' fluid />
                    <Modal.Footer className="background" >
                         some stuff here

The issue is it looks kind of messy. I would have to repeat each of the useStates a total of 6 times to render 6 different modal popups. Is there a cleaner way to do this?

Something I was thinking I’d like to do is like this:

<button onClick={()=>{
 <ModalPictures          // this would a separate component

but when I try this, it doesn’t actually do anything
any advice would be appreciated.

>Solution :

Only one or maybe two useStates are more than enough for what you’re trying to do. And just because you have 6 images you don’t need to use 6 modals.

I created a simple sandbox to show how this can be achieved. Click on any of the list items to see.

const arrayOfLength6 = Array(6)
  .map((_, i) => i);

const Modal = ({ show, data, onHide }) => {
  if (!show) return null;
  return (
      <button onClick={onHide}>Close</button>

export default function App() {
  const [selected, setSelected] = useState();

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
        { => (
          <li onClick={() => setSelected(i)} key={i}>
            I'm image at index {i}

        onHide={() => setSelected(undefined)}
        show={typeof selected !== "undefined"}

The idea is to keep track of the selected image in the state when it is clicked. In my example, I’m just storing the index of the image but you can store the data associated with an image when it’s selected and pass the data as props to the modal.

Leave a ReplyCancel reply