【问题标题】:material-ui Drawer - findDOMNode is deprecated in StrictModematerial-ui Drawer - findDOMNode 在 StrictMode 中已弃用
【发布时间】:2021-08-10 14:48:21
【问题描述】:

我有一个使用 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)))

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

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

谢谢

【问题讨论】:

  • 提交有关 Material-UI 的问题。或者 fork repo,修复它,发布 PR,使用你的 fork 直到 PR 被合并或 issue 被弃用。目前这只是一个警告,在第三方代码中。
  • 这里是讨论这个的问题:github.com/mui-org/material-ui/issues/13394
  • 感谢您的链接
  • 另外,请注意“使用ReactDOM.createRoot 和/或React.ConcurrentMode 时默认启用StrictMode。”。这里有一些很好的讨论:github.com/styled-components/styled-components/issues/2154
  • 当我使用 Tooltip 组件并将自定义组件传递给 title 道具而不是传递简单字符串时,我也会收到此错误!!!

标签: reactjs material-ui deprecation-warning react-navigation-drawer strict-mode


【解决方案1】:

根据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)。如果您可以选择升级 - 它也应该可以解决这个问题。

【讨论】:

  • 这应该是公认的答案。我不想仅仅因为 material-ui 更新缓慢而删除 StrictMode 并放弃它的所有好处。
  • 我明白为什么它不会被接受,因为它引用了一个“不稳定”的函数。对于我的用例,这个“不稳定”的函数看起来足够稳定并且可以完成工作,所以我可以专注于真正的警告而不会产生噪音。
  • 感谢您分享正确的解决方案。
  • 我们不接受这个作为答案并没有帮助社区,因为 Google 将索引优先级分配给已接受的答案。这不是第一个搜索结果,它确实应该是。
  • 这应该是正确的答案。谢谢
【解决方案2】:

这是StrictMode Warning

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

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

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

【讨论】:

  • 与生产无关。这发生在开发过程中。
  • 你可以跳过 直接渲染
【解决方案3】:

此警告是由于在许多 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;

【讨论】:

  • 非常有用的解决方案。也为我工作了对话。对我来说,查看 github 上的默认实现以了解默认使用的转换组件是有帮助的。 github.com/mui-org/material-ui/tree/next/packages/material-ui/… 对于对话框,TransitionComponent 是:const DialogTransition = forwardRef((props: FadeProps, ref) =&gt; &lt;Fade ref={ ref } { ...props } /&gt;)
  • 只需在父级中添加 const variableNameRef = createRef() 并将 ref={variableNameRef} 传递给 Dawer 组件即可为我消除错误。这让我找到了那个解决方案,谢谢。
【解决方案4】:

更改您的主题配置

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

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

生成一个主题来减少 React.StrictMode 中的警告数量,例如 Warning: findDOMNode is deprecated in StrictMode。

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

用于生产用途 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')
);

【讨论】:

    【解决方案5】:

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

    React StrictMode 此错误在以下部分中引用:

    关于不推荐使用 findDOMNode 的警告

    这里是一个示例 sn-p,指示如何解决问题。看起来我们需要创建一个 React Ref,然后将该 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-02-26
    • 1970-01-01
    • 2020-12-15
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多