Materials-ui Drawer-findDOMNode 在 StrictMode 中不推荐使用

我有一个简单的 ReactJS 应用程序,它使用 StrictMode,基于 hook (没有类)。

我使用的是 React version 16.13.1和 Materials-UI version 4.9.10。

在 Appbar 中我正在使用 Drawer。

    <div className={classes.root}>
<AppBar position="static">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="menu"
onClick={handleDrawerOpen}>
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
Online Information
</Typography>
</Toolbar>
</AppBar>
<Drawer
variant="persistent"
anchor="left"
open={open}
></Drawer>
</div>

我注意到,当我打开抽屉,我得到以下警告。

Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance
of
Transition which is inside StrictMode. Instead, add a ref directly to the element you
want to reference. Learn more about using refs safely ....
in div (created by Transition)
in Transition (created by ForwardRef(Fade))
in ForwardRef(Fade) (created by ForwardRef(Backdrop))
in ForwardRef(Backdrop) (created by WithStyles(ForwardRef(Backdrop)))
in WithStyles(ForwardRef(Backdrop)) (created by ForwardRef(Modal))
in div (created by ForwardRef(Modal))
in ForwardRef(Portal) (created by ForwardRef(Modal))
in ForwardRef(Modal) (created by ForwardRef(Drawer))
in ForwardRef(Drawer) (created by WithStyles(ForwardRef(Drawer)))

我在网上找到了一些关于这个问题的参考资料,但仍然不知道如何解决这个问题。

有人能为这个问题增加一些解决方案吗?

谢谢你

74463 次浏览

这是 StrictMode 警告

严格的模式检查仅在开发模式下运行; 它们不会影响生产构建。

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

ReactDOM.render(
<App />,
document.getElementById('root')
);

根据资料 -ui 更改日志,它应该在 V5中解决,这仍然在 alpha 中。

看起来至少在某些情况下这个问题是由 createMuiTheme引起的。您可以通过使用实验性(不稳定的)主题创建器来解决这个问题

如果你想得到实验性的主题创建器而不是删除 React.StrictMode,你可以改变它的导入:

import { createMuiTheme } from '@material-ui/core';


import { unstable_createMuiStrictModeTheme as createMuiTheme } from '@material-ui/core';


更新

V5正式退出(现在称为 )。如果升级是你的一个选择-它应该解决这个问题以及。

这个警告是由于产品化组件,它被用于很多材料-ui 组件,如 Drawer,Tooltip,Snackbar 等。

就个人而言,我在所有这些组件中都遇到了这个警告,但是只在 Snackbar 组件中修复了这个问题。

解决方案是创建一个 ref 并将其传递到根组件。然后,手动将引用转发到使用产品化的子组件。

下面是 Snackbar 组件的代码,它为我解决了这个问题。既然这只是一个警告,也许你可以忽略它。您不需要删除 StrictMode。它将固定在未来的材料-用户界面发布。

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';


//MUI Stuff
import { makeStyles } from '@material-ui/core/styles';
import Snackbar from '@material-ui/core/Snackbar';
import MuiAlert from '@material-ui/lab/Alert';


// Redux
import { hideAlert } from '../../redux/actions/uiActions';
import Slide from '@material-ui/core/Slide';


const Alert = React.forwardRef((props, ref) => {
return <MuiAlert ref={ref} elevation={6} variant="filled" {...props} />;
});


const SlideTransition = React.forwardRef((props, ref) => {
return <Slide ref={ref} {...props} direction="left" />;
});


const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
snackbar: {
[theme.breakpoints.down('sm')]: {
bottom: 65,
},
},
}));


const SnackAlert = () => {
const snackbarRef = React.createRef(null);
const classes = useStyles();
const { alert, alertType, alertMessage } = useSelector((state) => ({
alert: state.ui.alert,
alertType: state.ui.alertType,
alertMessage: state.ui.alertMessage,
}));
const dispatch = useDispatch();
const [open, setOpen] = React.useState(false);


useEffect(() => {
setOpen(alert);
}, [alert]);


const handleClose = () => {
setOpen(false);
dispatch(hideAlert());
};


return (
<div className={classes.root}>
<Snackbar
ref={snackbarRef}
className={classes.snackbar}
open={open}
anchorOrigin=\{\{ vertical: 'bottom', horizontal: 'right' }}
autoHideDuration={5000}
onClose={handleClose}
message={alertMessage}
TransitionComponent={SlideTransition}
>
<Alert onClose={handleClose} severity={alertType}>
{alertMessage}
</Alert>
</Snackbar>
</div>
);
};
export default SnackAlert;

更改主题配置

import { createMuiTheme } from '@material-ui/core';

import { unstable_createMuiStrictModeTheme as createMuiTheme } from '@material-ui/core';

生成一个主题,该主题可以减少 React 内部的警告数量。

警告: 不要在生产中使用此方法。

对于生产,使用 import { createMuiTheme } from '@material-ui/core';并将 StrictMode 替换为片段。

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

ReactDOM.render(
<React.Fragment>
<App />
</React.Fragment>,
document.getElementById('root')
);