React-table每行加MUI Menu遇StrictMode警告,求非关闭StrictMode方案
我尝试为React-table的每一行末尾添加带MUI Menu的展开操作按钮,但出现如下警告:
react_devtools_backend.js:2655 Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Transition2 which is inside StrictMode. Instead, add a ref directly to the element you want to reference.
请问有没有无需关闭StrictMode的解决办法?相关代码如下:
import MoreVertIcon from '@mui/icons-material/MoreVert'; import { IconButton, Menu, MenuItem } from '@material-ui/core'; import React, { useState, useMemo } from 'react'; import { useTable } from 'react-table'; import { ContentWrapper } from '~/components/Content/ContentWrapper'; import { DataGrid } from '~/components/Table/Table'; const Example = () => { const [anchorEl, setAnchorEl] = useState(null); const columns = useMemo(() => COLUMNS, []); const data = useMemo(() => MOCK_DATA, []); const tableInstance = useTable( { columns, data, }, hooks => { hooks.visibleColumns.push(columns => [ ...columns, { id: 'actions', Cell: () => { return ( <TableActionButton setAnchorEl={setAnchorEl} anchorEl={anchorEl} /> ); }, }, ]); }, ); return ( <ContentWrapper> <DataGrid tableInstance={tableInstance} /> </ContentWrapper> ); }; const TableActionButton = ({ setAnchorEl, anchorEl }) => { return ( <> <IconButton onClick={e => setAnchorEl(e.currentTarget)}> <MoreVertIcon /> </IconButton> <Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={() => setAnchorEl(null)}> <MenuItem>Profile</MenuItem> <MenuItem>My account</MenuItem> <MenuItem>Logout</MenuItem> </Menu> </> ); };
问题根源
- MUI旧版本的Menu组件内部依赖
findDOMNode定位锚点,而StrictMode下该API已被弃用 - 所有行共用同一个
anchorEl状态,不仅会导致警告,还可能引发菜单状态混乱
解决办法
1. 让每个行的Menu拥有独立状态
将Menu的状态从父组件移到TableActionButton内部,避免全局状态冲突,同时减少不必要的组件渲染。
2. 优化Menu组件配置
给Menu添加ref,并通过明确锚点位置的属性,替代内部的findDOMNode调用;若仍有警告,可尝试关闭菜单的portal特性。
修改后的完整代码:
import MoreVertIcon from '@mui/icons-material/MoreVert'; import { IconButton, Menu, MenuItem } from '@material-ui/core'; import React, { useState, useMemo, useRef } from 'react'; import { useTable } from 'react-table'; import { ContentWrapper } from '~/components/Content/ContentWrapper'; import { DataGrid } from '~/components/Table/Table'; const Example = () => { const columns = useMemo(() => COLUMNS, []); const data = useMemo(() => MOCK_DATA, []); const tableInstance = useTable( { columns, data, }, hooks => { hooks.visibleColumns.push(columns => [ ...columns, { id: 'actions', Cell: () => <TableActionButton />, }, ]); }, ); return ( <ContentWrapper> <DataGrid tableInstance={tableInstance} /> </ContentWrapper> ); }; const TableActionButton = () => { const [anchorEl, setAnchorEl] = useState(null); const menuRef = useRef(null); const handleOpen = (event) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; return ( <> <IconButton onClick={handleOpen}> <MoreVertIcon /> </IconButton> <Menu ref={menuRef} anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleClose} anchorOrigin={{ vertical: 'top', horizontal: 'right' }} transformOrigin={{ vertical: 'top', horizontal: 'right' }} // 若警告仍存在,可尝试开启下面的配置 // disablePortal={true} > <MenuItem onClick={handleClose}>Profile</MenuItem> <MenuItem onClick={handleClose}>My account</MenuItem> <MenuItem onClick={handleClose}>Logout</MenuItem> </Menu> </> ); };
额外建议
如果使用的是Material-UI v4及以下版本,建议升级到MUI v5——v5已全面替换findDOMNode为ref引用,从根源解决StrictMode下的兼容性问题。
内容的提问来源于stack exchange,提问作者Stairss
相关产品推荐
相关产品推荐

