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

Jotai自定义Modal中回调获取状态始终为初始值问题求助

Jotai Modal中handleCreateUser始终获取formCreateData初始值

代码实现

定义Modal状态Atom

import { atom } from "jotai"

type ActionsType = {
  text: string
  onClick: () => void
  element: JSX.Element
}

export type ModalContentType = {
  title: string
  actions: ActionsType[] | []
  children: JSX.Element | null
  visible: boolean
}

export const modalContent = atom<ModalContentType>({
  title: "",
  actions: [],
  children: null,
  visible: false,
})

Modal组件实现

export default function ModalComponent(): JSX.Element {
  const [modalContent, setModalContent] = useAtom(modalContentAtom)

  // 其他事件与函数

  return (
    <ModalWrapper $visible={modalContent.visible} onClick={closeModal}>
      <ModalContent
        key={modalContent.visible ? "visible" : "hidden"}
        variants={variants}
        initial="hidden"
        animate="enter"
        exit="exit"
        role="dialog"
      >
        <ModalHeader>
          <ModalTitle>{modalContent.title}</ModalTitle>
          <ModalClose onClick={handleCloseModal} id="close-modal" role="button">
            <GrClose />
          </ModalClose>
        </ModalHeader>
        {modalContent.children}
        <ModalFooterWrapper>
          {modalContent.actions.map((action: any) =>
            React.cloneElement(action.element, { ...action.element.props, onClick: action.onClick })
          )}
        </ModalFooterWrapper>
      </ModalContent>
    </ModalWrapper>
  )
}

触发Modal的按钮逻辑

return (
    <UsersLayout>
      <TableAdmin columns={Object.keys(users[0] || {})} data={users} />
      <Actions>
        <ActionButton
          type="button"
          onClick={() => {
            setModalContent({
              visible: true,
              title: translations.create,
              children: <CreateUserComponent />,
              actions: [
                {
                  text: translations.cancel,
                  onClick: () => setModalContent({ ...modalContent, visible: false }),
                  element: CancelButtonElement,
                },
                {
                  text: translations.create,
                  onClick: handleCreateUser,
                  element: UpdateButtonElement,
                },
              ],
            })
          }}
        >
          Create
        </ActionButton>
       {/* 其他按钮 */}
      </Actions>
    </UsersLayout>

问题函数与测试Effect

const handleCreateUser = async (): Promise<void> => {
    setLoadingBar(true)
    // await createUserMutation(formCreateData)
    console.log(formCreateData)
    setLoadingBar(false)
  }
useEffect(() => {
    console.log(formCreateData)
  }, [formCreateData])

核心问题

  • 依赖formCreateData的useEffect能正常打印状态更新后的最新值
  • handleCreateUser函数中始终打印formCreateData的初始值,无法获取最新状态
  • 已尝试优化方案:给handleCreateUser添加useCallback、抽离ActionButton为独立组件、将打开Modal的回调移到渲染外部,均未解决问题

内容的提问来源于stack exchange,提问作者Hidenplus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 18:10:28