Chakra UI 在单个组件中使用多个模型

问题描述 投票:0回答:6

我正在使用 Chakra UI,我想在单个组件中使用两个模态。

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
onClose
不能作为变量更改,因为它们是内置的 Chakra 函数。

有人可以建议我一种方法来改变其中两个模态(Chakra UI)操作吗?

reactjs modal-dialog chakra-ui
6个回答
29
投票

您可以简单地更改变量的名称

isOpen
onOpen
onClose
走吧:

const { isOpen: isEditOpen , onOpen: onEditOpen, onClose: onEditClose } = useDisclosure()
const { isOpen: isDeleteOpen , onOpen: onDeleteOpen, onClose: onDeleteClose } = useDisclosure()

{/* Edit Button*/}
<Button colorScheme="teal" size="xs" mr='2' onClick={onEditOpen} >
    Edit
</Button>

{/* Edit Modal */}
<Modal isOpen={isEditOpen} onClose={onEditClose}>
    <ModalOverlay />
    <ModalContent>
    <ModalHeader>Edit Modal</ModalHeader>
    <ModalCloseButton />
    <ModalBody>
        Edit Modal
    </ModalBody>
    <ModalFooter>
    <Button variant="ghost" mr={3} onClick={onEditClose}>Cancel</Button>
        <Button colorScheme="red" onClick={()=>{deleteAddress(address.id)}}>
            Delete
        </Button>
    </ModalFooter>
    </ModalContent>
</Modal>


{/* Delete Button*/}
<Button colorScheme="red" size="xs"  onClick={onDeleteOpen}>
    Delete
</Button> 

{/* Delete Modal*/}
<Modal isOpen={isDeleteOpen} onClose={onSecondModalClose}>
    <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={onDeleteClose}>Cancel</Button>
        <Button colorScheme="red" onClick={()=>{deleteAddress(address.id)}}>
            Delete
        </Button>
    </ModalFooter>
    </ModalContent>
</Modal>

再举一个例子:

第一个模态:

const { isOpen: isFirstModalOpen , onOpen: onFirstModalOpen, onClose: onFirstModalClose } = useDisclosure()

第二个模态:

const { isOpen: isSecondModalOpen , onOpen: onSecondModalOpen, onClose: onSecondModalClose } = useDisclosure()

现在这些变量具有不同的值,因此您可以在任何地方使用新名称!


14
投票

您可以创建一个使用

useDisclosure
的自定义模态组件。然后,您可以拥有此自定义模态组件的多个实例,而无需模态共享相同的状态:

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>
  );
}

这样

CustomModal
的每个实例都会跟踪自己的
isOpen
onOpen
onClose
状态。

由于在您的问题中,唯一的动态部分是打开按钮、模式、标题文本和模式正文文本,因此我制作了道具,以便可以为每个实例单独设置这些道具。如果更多部件需要动态,您可以根据需要添加道具。

我对模态做了一些小改动,以使其更容易测试。


3
投票

您可以简单地创建两个 useDisclosure 钩子实例。

  const {
    isOpen: isAssociationModalOpen,
    onOpen: onOpenAssociationModal,
    onClose: onCloseAssociationModal,
  } = useDisclosure();
  const {
    isOpen: isRevocationModalOpen,
    onOpen: onOpenRevocationModal,
    onClose: onCloseRevocationModal,
  } = useDisclosure();

1
投票

所以基本上你可以更改变量的名称 isOpen、onOpen 和 onClose,或者你可以有两个 useDisclosure 实例,这样你就可以在代码中使用两个或多个模态:

import React, { useState } from 'react'
import { data } from '../../../utils/Data/data'
import {
    Table,
    Thead,
    Tbody,
    Tfoot,
    Tr,
    Th,
    Td,
    Checkbox,
    CheckboxGroup,
    Skeleton,
    Box,
    VStack,
    Button,
    HStack,
    useDisclosure


} from '@chakra-ui/react'
import EditSiteModal from '../Modal/EditSiteModal'
import DeleteSiteModal from '../Modal/DeleteSiteModal'

const MySites = () => {
    const { isOpen: isEditOpen, onOpen: onEditOpen, onClose: onEditClose } = useDisclosure()
    const { isOpen: isDeleteOpen, onOpen: onDeleteOpen, onClose: onDeleteClose } = useDisclosure()


    return (
        <>
            <Box bgColor="white" p={10}>
                <Box bgColor="white">
                    <EditSiteModal
                        isOpen={isEditOpen}
                        onClose={onEditClose}
                    />

                    <DeleteSiteModal
                        isOpen={isDeleteOpen}
                        onClose={onDeleteClose}
                    />

                    <Table variant='simple'>
                        <Thead>
                            <Tr bg="#F9F9F9" p="2" >
                                <Th></Th>
                                <Th textTransform={'capitalize'}>Site Name</Th>
                                <Th textTransform={'capitalize'}>Admin</Th>
                                <Th textTransform={'capitalize'}>Creation date & Time</Th>
                                <Th textTransform={'capitalize'}>Actions</Th>
                            </Tr>
                        </Thead>

                        <Tbody>

                            {data &&
                                data.map((sites, index: number) => {

                                    return (
                                        <Tr key={index} cursor={"pointer"}>
                                            <Td><Checkbox></Checkbox></Td>
                                            <Td>{sites.site_name}</Td>
                                            <Td>{sites.admin}</Td>
                                            <Td>{sites.creation_date}</Td>
                                            <Td>
                                                <HStack>
                                                    <Button
                                                        type="button"
                                                        bg="transparent"
                                                        border="1px"
                                                        borderRadius="base"
                                                        borderColor="#1818183D"
                                                        width="inherit"
                                                        onClick={onDeleteOpen}
                                                        mr="8px"
                                                    >
                                                        Delete
                                                    </Button>
                                                    <Button
                                                        type="button"
                                                        bg="transparent"
                                                        border="1px"
                                                        borderRadius="base"
                                                        borderColor="#F6B319"
                                                        width="inherit"
                                                        onClick={onEditOpen}
                                                    >
                                                        Edit
                                                    </Button>
                                                </HStack>
                                            </Td>
                                        </Tr>
                                    );
                                })}
                        </Tbody>
                    </Table>
                </Box>
            </Box>
        </>
    )
}

export default MySites

1
投票

其他答案不包括您需要映射许多元素并让每个元素在单击时打开一个包含其值的模式的情况。

这里有一个方法:

  • 允许所有这些元素打开同一个模态
  • 使用
    useState
  • 更改该模式的内容

如何:

  • 在每个元素的
    onClick
    中,调用一个函数:使用其值设置状态 + 调用
    useDisclosure
    onOpen()
  • 只需使用模态中的状态值

您可以通过在此页面上搜索“modal”一词来查看示例(包含

const [modalValue, setModalValue] = useState({})
的代码部分):https://www.educative.io/answers/how-to-make-a-chakra- ui-and-react-to-do-list-app-using-hooks-only


0
投票

我在我的项目中也遇到过同样的情况。这就是我解决这个问题的方法:

function MyApp() {
  const modal1 = useDisclosure()
  const modal2 = useDisclosure()
  
  return (
    <>
      <Button onClick={modal1.onOpen}>Open Modal 1</Button>
      <Button onClick={modal2.onOpen}>Open Modal 2</Button>

      <Modal isOpen={modal1.isOpen} onClose={modal1.onClose}>
        // modal body
      </Modal>
      
      <Modal isOpen={modal2.isOpen} onClose={modal2.onClose}>
        // modal body
      </Modal>
    </>
  )
}

您可以根据您的场景使用

editModal
deleteModal

© www.soinside.com 2019 - 2024. All rights reserved.