如何在Chakra UI中从子组件触发关闭Modal弹窗?
解决方案
下面提供3种不同复杂度场景下的实现方案,可根据你的项目实际情况选择:
方案1:透传onClose属性(最推荐,简单场景直接使用)
第一步:修改父组件,把关闭方法作为props传给子组件
// 父组件Post代码 import {Post as PostModal} from '../components/Modal' import { useDisclosure, Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody } from '@chakra-ui/react' export const Post = () => { const { isOpen, onOpen, onClose } = useDisclosure() return ( <div> <Modal onClose={onClose} size='full' isOpen={isOpen} trapFocus={false} > <ModalOverlay /> <ModalContent> <ModalHeader>Add Post</ModalHeader> <ModalCloseButton /> <ModalBody> <div> {/* 把onClose作为props传给子组件 */} <PostModal onClose={onClose} /> </div> </ModalBody> </ModalContent> </Modal> </div> ) }
第二步:修改子组件代码,接收onClose并在请求成功后调用
// /components/Modal 代码 // fetcher接收onClose作为参数 const fetcher = async (data, onClose) => { const res = await sendPost(data); if (res) { // 请求成功后调用关闭方法 onClose() } } // 子组件接收onClose prop const PostInput = ({onClose}) => { // 提交表单的触发逻辑示例 const handleSubmit = async (formData) => { await fetcher(formData, onClose) } return ( // 你的输入组件内容,提交时触发handleSubmit即可 // <Input/> // <Textarea> etc... ) } export { PostInput as Post }
方案2:使用React Context(适合组件嵌套层级深,透传props麻烦的场景)
第一步:创建Modal上下文
// src/context/ModalContext.js import { createContext, useContext } from 'react' const ModalContext = createContext() export const ModalProvider = ModalContext.Provider export const useModalContext = () => useContext(ModalContext)
第二步:父组件引入Provider注入onClose
import { ModalProvider } from 'src/context/ModalContext' // 其余父组件引入保持不变 export const Post = () => { const { isOpen, onOpen, onClose } = useDisclosure() return ( <div> <Modal onClose={onClose} size='full' isOpen={isOpen} trapFocus={false} > <ModalOverlay /> <ModalContent> <ModalHeader>Add Post</ModalHeader> <ModalCloseButton /> <ModalBody> <div> {/* 注入onClose到上下文 */} <ModalProvider value={{onClose}}> <PostModal /> </ModalProvider> </div> </ModalBody> </ModalContent> </Modal> </div> ) }
第三步:子组件内从上下文取onClose调用
// /components/Modal 代码 import { useModalContext } from 'src/context/ModalContext' const fetcher = async (data, onClose) => { const res = await sendPost(data); if (res) { onClose() } } const PostInput = () => { // 从上下文拿到关闭方法 const { onClose } = useModalContext() const handleSubmit = async (formData) => { await fetcher(formData, onClose) } return ( // 输入组件内容 ) } export { PostInput as Post }
方案3:全局状态管理(适合大型项目,Modal状态需要全局共享的场景)
可以把Modal的isOpen状态和关闭方法存在Zustand/Redux等全局状态库中,子组件提交成功后直接调用全局的关闭方法即可,不需要做父子组件的状态传递。
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

