skip to Main Content

I have the following model dialog box:

// Modal.tsx

import React, { ReactNode } from "react";

interface ModalType {
  children?: ReactNode;
  isOpen: boolean;
  toggle: () => void;
}

export default function Modal(props: ModalType) {
  return (
    <>
      {props.isOpen && (
        <div className="modal-overlay" onClick={props.toggle}>
          <div onClick={(e) => e.stopPropagation()} className="modal-box max-w-md bg-[#323F5F]">
            {props.children}
          </div>
        </div>
      )}
    </>
  );
}

and I access this model dialog like the following:

import { useState } from "react";

const Index = () => {

    const [isOpen, setisOpen] = useState(false);
    
    <div onClick={() => setisOpen(!isOpen)}>Dialog 1</div>
    <div onClick={() => setisOpen(!isOpen)}>Dialog 2</div>
    
    <Modal isOpen={isOpen} toggle={() => setisOpen(!isOpen)}>
     Dialog 1 content
    </Modal>

    <Modal isOpen={isOpen} toggle={() => setisOpen(!isOpen)}>
     Dialog 2 content
    </Modal>

}

Here, I am trying to create multiple models using the model component, without defining separate state variables for each one. Is it possible to access each model separately without the need for a separate state variable for each one?

2

Answers


  1. If I understand you correctly – you can always create a object i.e Record<number, boolean> or array to keep each state for Modal separate in one useState. Then you would create a component which maps over this state and creates modal if it meet it’s isOpen condition. The toggle function would look like this, but you could always create the toggles dynamically.

    const [modals, setModals] = useState([false, false]);
    
    function handleToggleFirstModal(newState) { setModals(prevState => [!prevState[0], ...prevState]) };
    
    Login or Signup to reply.
  2. You can just use an array in the state variable, with element i indicating the open state of modal i:

    const Index = () => {
        const [open, setOpen] = useState([false, false]);
        const toggleOpen = (i) => setOpen(open => {
            const newOpen = [...open];
            newOpen[i] != open[i];
            return newOpen;
        });
    
        return <div>
            <div onClick={() => toggleOpen(0)}>
                Dialog 1
            </div>
            <div onClick={() => toggleOpen(1)}>
                Dialog 2
            </div>
            <Modal isOpen={open[0]} toggle={() => toggleOpen(0)}>
                Dialog 1 content
            </Modal>    
            <Modal isOpen={open[1]} toggle={() => toggleOpen(1)}>
                Dialog 2 content
            </Modal>
        </div>;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search