You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 18:45:04