如何存储组件实现条件渲染,解决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
相关产品推荐
相关产品推荐

