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

IT技术 reactjs material-ui deprecation-warning react-navigation-drawer strict-mode
2021-03-26 03:24:45

我有一个使用 StrictMode 的基于钩子(无类)的简单 ReactJS 应用程序。

我使用的是 React 版本 16.13.1 和 Material-UI 版本 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)))

我在网上找到了有关此问题的一些参考资料,但仍然无法弄清楚如何解决此问题。

有人可以为这个问题添加一些解决方法吗?

谢谢

5个回答

根据 Material-ui changelog,应该是在 V5 中解决的,目前还处于 alpha 阶段。

似乎至少在某些情况下这个问题是由createMuiTheme. 您可以使用实验性(不稳定)主题创建器来解决此问题

如果您想获取实验主题创建者而不是删除React.StrictMode,您可以更改它的导入:

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

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

更新

V5 正式发布(现在称为MUI)。如果升级是您的选择 - 它也应该解决这个问题。

这应该是正确答案。谢谢
2021-05-24 03:24:45
这应该是公认的答案。我不想StrictMode仅仅因为 material-ui 更新缓慢就删除和丢弃它的所有好处。
2021-06-09 03:24:45
我们不接受此作为答案并没有帮助社区,因为 Google 为已接受的答案提供了索引优先级。这不是第一个搜索结果,它确实应该是。
2021-06-12 03:24:45
感谢您分享正确的解决方案。
2021-06-16 03:24:45
我可以理解为什么它不是公认的答案,因为它引用了一个“不稳定”的函数。对于我的用例,这个“不稳定”函数看起来足够稳定并且可以完成工作,所以我可以专注于真正的警告而没有噪音。
2021-06-18 03:24:45

这是StrictMode 警告

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

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

ReactDOM.render(
    <App />,
  document.getElementById('root')
);
你可以跳过 <React.Fragment> 只渲染 <App />
2021-06-02 03:24:45
它与生产无关。这发生在开发过程中。
2021-06-18 03:24:45

此警告是由于许多 Material-ui 组件(如 Drawer、Tooltip、Snackbar 等)中使用的 Transition 组件造成的。

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

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

这是 Snackbar 组件的代码,它为我解决了这个问题。由于它只是一个警告,因此可能会忽略它。您不需要删除 StrictMode。它将在未来的 material-ui 版本中修复。

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;
只需在父级中添加 const variableNameRef = createRef() 并将 ref={variableNameRef} 传递给 Dawer 组件,就为我消除了错误。这使我找到了解决方案,谢谢。
2021-06-05 03:24:45
非常有帮助的解决方案。也为我工作了对话。对我来说,查看 github 上的默认实现以找出默认使用的转换组件很有帮助。github.com/mui-org/material-ui/tree/next/packages/material-ui/... 对于 DialogTransitionComponent是:const DialogTransition = forwardRef((props: FadeProps, ref) => <Fade ref={ ref } { ...props } />)
2021-06-06 03:24:45

更改主题配置

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

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

生成一个主题,以减少 React.StrictMode 中的警告数量,例如警告:在 StrictMode 中不推荐使用 findDOMNode。

警告:请勿在生产中使用此方法。

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

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

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

我在尝试使用 React material Select 组件进行选择时遇到了同样的错误。我在 React 文档中找到了这个页面,该页面讨论了严格模式并引用了这个特定的错误。

React StrictMode 部分中引用了此错误:

有关已弃用的 findDOMNode 用法的警告

这是指示如何解决问题的示例代码段。看起来我们需要创建一个 React Ref,然后将该引用附加到抛出错误的 DOM 节点。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.wrapper = React.createRef();
  }
  render() {
    return <div ref={this.wrapper}>{this.props.children}</div>;
  }
}
这对问题中的代码有何作用?
2021-06-01 03:24:45
请在发布答案之前测试代码
2021-06-04 03:24:45