Search code examples
reactjsmodal-dialogchakra-ui

Chakra UI using multiple models in a single component


I am using Chakra UI and I want to use two modals in a single component.

const { isOpen , onOpen, onClose } = useDisclosure()

 <Button colorScheme="teal" size="xs" mr='2' onClick={onOpen} >
                        Edit
                    </Button>
                    {/* Edit modal */}
                    <Modal isOpen={isOpen} onClose={onClose}>
                            <ModalOverlay />
                            <ModalContent>
                            <ModalHeader>Edit Modal</ModalHeader>
                            <ModalCloseButton />
                            <ModalBody>
                               Edit Modal
                            </ModalBody>

                            <ModalFooter>
                            <Button variant="ghost" mr={3} onClick={onClose}>Cancel</Button>
                                <Button colorScheme="red" onClick={()=>{deleteAddress(address.id)}}>
                                    Delete
                                </Button>
                                
                            </ModalFooter>
                            </ModalContent>
                        </Modal>


                    {/* Delete Address */}

                    <Button colorScheme="red" size="xs"  onClick={onOpen}>
                        Delete
                    </Button> 
                    <Modal isOpen={isOpen} onClose={onClose}>
                            <ModalOverlay />
                            <ModalContent>
                            <ModalHeader>Delete Shipping Address</ModalHeader>
                            <ModalCloseButton />
                            <ModalBody>
                                Are you sure you want to delete the shipping address?
                            </ModalBody>

                            <ModalFooter>
                            <Button variant="ghost" mr={3} onClick={onClose}>Cancel</Button>
                                <Button colorScheme="red" onClick={()=>{deleteAddress(address.id)}}>
                                    Delete
                                </Button>
                                
                            </ModalFooter>
                            </ModalContent>
                        </Modal>

isOpen, onOpen and onClose can't be changed as variables since they are inbuilt Chakra functions.

Can someone suggest me a method to variate two of these modal (Chakra UI) operations?


Solution

  • You could create a custom modal component that uses useDisclosure. Then you can have multiple instances of this custom modal component without the modals sharing the same state:

    const CustomModal = ({ showModalButtonText, modalHeader, modalBody }) => {
      const { isOpen, onOpen, onClose } = useDisclosure();
      return (
        <>
          <Button colorScheme="red" size="xs" onClick={onOpen}>
            {showModalButtonText}
          </Button>
          <Modal isOpen={isOpen} onClose={onClose}>
            <ModalOverlay />
            <ModalContent>
              <ModalHeader>{modalHeader}</ModalHeader>
              <ModalCloseButton />
              <ModalBody>{modalBody}</ModalBody>
    
              <ModalFooter>
                <Button variant="ghost" mr={3} onClick={onClose}>
                  Cancel
                </Button>
                <Button
                  colorScheme="red"
                  onClick={() => {
                    alert(1);
                  }}
                >
                  Delete
                </Button>
              </ModalFooter>
            </ModalContent>
          </Modal>
        </>
      );
    };
    
    export default function App() {
      return (
        <div className="App">
          <CustomModal
            showModalButtonText="Edit"
            modalHeader="Edit Modal"
            modalBody="Edit Modal"
          />
          <CustomModal
            showModalButtonText="Delete"
            modalHeader="Delete Shipping Address"
            modalBody="Are you sure you want to delete the shipping address?"
          />
        </div>
      );
    }
    

    This way each instance of CustomModal keeps track of its own isOpen, onOpen and onClose state.

    Since in your question the only dynamic parts were the button for opening, the modal, the header text and the modal body text, I've made props so these can be set separately for each instance. If more parts need to be dynamic you can add props as needed.

    I've changed some small things to the modal to make it easier to test.