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

如何存储组件实现条件渲染,解决Material-UI Popover内Formik表单值清空问题

问题根因

Material-UI 的 Popover 组件默认在关闭状态(open={false})下会直接卸载内部所有子节点,下次打开时会重新渲染挂载传入的children,所以你放在内部的 Formik 表单状态会在每次关闭 Popover 时被完全重置。

解决方案

直接给 Popover 组件添加 keepMounted={true} 属性即可,该属性会让 Popover 关闭时仅通过 CSS 隐藏内部内容,不会卸载子节点,所有内部组件的状态都会完整保留,不需要修改父组件的状态存储逻辑,也能适配你的动态组件使用场景。

修改后完整代码

import { useState } from 'react';
import IconButton from '@mui/material/IconButton';
import Popover from '@mui/material/Popover';

export default function ButtonPopover({ icon: Icon, children }) {
  const [anchorEl, setAnchorEl] = useState(null);

  const open = (event) => {
    setAnchorEl(event.currentTarget);
  };

  const close = () => {
    setAnchorEl(null);
  };

  return (
    <>
      <IconButton onClick={open}>
        <Icon />
      </IconButton>
      <Popover
        open={Boolean(anchorEl)}
        anchorEl={anchorEl}
        onClose={close}
        keepMounted={true} // 新增该行配置即可
        anchorOrigin={{
          vertical: "bottom",
          horizontal: "center",
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "center",
        }}
      >
        {children}
      </Popover>
    </>
  );
}

补充说明

如果你的 Popover 内部内容体积非常大,担心长期挂载占用少量内存,也可以搭配disablePortal属性使用,常规表单场景下不需要额外配置,上述修改即可满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 02:39:02