140

I have a simple ReactJS app based on hooks (no classes) using StrictMode.

I am using React version 16.13.1 and Material-UI version 4.9.10.

In the Appbar I am using 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>

I notice that when I open the Drawer, I get the following warning.

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)))

I found some reference on the web for this issue but still can’t figure out how to resolve this issue.

Can someone please add some workaround for this problem?

Thank you

Zach
  • 539
  • 1
  • 4
  • 22
angus
  • 3,210
  • 10
  • 41
  • 71
  • 3
    File an issue with Material-UI. Or fork the repo, fix it, issue PR, use your fork till PR is merged or issue is deprecated. It's just a warning for now, in third-party code. – Drew Reese Apr 15 '20 at 02:55
  • 7
    Here's the issue that discusses this: https://github.com/mui-org/material-ui/issues/13394 – Ryan Cogswell Apr 15 '20 at 14:13
  • Thank you for the link – angus Apr 15 '20 at 23:25
  • 2
    Also, note that "`StrictMode` is enabled by default when using `ReactDOM.createRoot` and/or `React.ConcurrentMode`.". there are some good discussions here: https://github.com/styled-components/styled-components/issues/2154 – Mahdi Abdi May 18 '20 at 09:30
  • 1
    I also get this error when I use the **Tooltip** component and pass a custom component to the `title` props instead of passing a simple string!!! – Alireza Kavian Jan 31 '21 at 12:57

4 Answers4

250

According to Material-ui changelog, it should be solve in V5, which is still in alpha.

It seems that at least in some cases this issue cause by createMuiTheme. You can solve this issue by using the experimental (unstable) theme creator

If you want to get the experimental theme creator instead of removing React.StrictMode, you can change it's import from:

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

To

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

UPDATE

V5 is officially out (and now called MUI). If upgrading is an option for you - it should solve this issue as well.

yuval.bl
  • 4,890
  • 3
  • 17
  • 31
  • 47
    This should be the accepted answer. I don't want to remove `StrictMode` and discard all of its benefits just because material-ui is slow to update. – NearHuscarl Oct 22 '20 at 19:41
  • 4
    I can see why it won't be the accepted answer, because it is referencing an "unstable" function. For my usecase, this "unstable" function looks stable enough and gets the job done, so I can concentrate on the real warnings without the noise. – TheDiveO Nov 12 '20 at 08:49
  • 2
    Thank you for sharing the correct solution. – Martin Najjar Feb 08 '21 at 21:58
  • 2
    We're not helping the community by not accepting this as the answer, because Google gives indexing priorities to accepted answers. This was not the first search result, and it really should be. – Reactgular Feb 22 '21 at 14:15
  • 2
    this should be the correct answer. thanks – Chrisk8er Feb 28 '21 at 02:00
  • Could you help me understand how to use `unstable_createMuiStrictModeTheme` to solve the problem? In my code I simply use a standard material UI `Dialog` and nowhere I mention or use `createMUITheme` so I do not know how to apply this solution. – Picci Mar 08 '21 at 11:45
  • 1
    @Picci check the curstomization section: https://material-ui.com/customization/theming/ – Jeffrey Nicholson Carré Mar 15 '21 at 20:30
  • 1
    @Jeffrey Nicholson Carré Thanks, it was the right place. `const theme = unstable_createMuiStrictModeTheme();` creates the theme and `` is the way to use it. I added it to the top App component. – Picci Mar 15 '21 at 21:53
  • @Picci and @Jeffrey Nicholson Carré, an import (`import { ThemeProvider } from '@material-ui/core/styles';`) is needed to use ThemeProvider this way. This approach is working for me so far and I agree it should be the accepted answer. – Tom Stambaugh Mar 29 '21 at 20:30
  • Warning - When using this solution with material-ui/core 4.11.3 and the `Snackbar` component you will get the following exception: `Error: Uncaught Error: TypeError: Cannot read property 'scrollTop' of null` – Ogglas Apr 01 '21 at 12:31
41

This is a StrictMode Warning

Strict mode checks are run in development mode only; they do not impact the production build.

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

to

ReactDOM.render(
    <App />,
  document.getElementById('root')
);
Zach
  • 539
  • 1
  • 4
  • 22
Lashan Fernando
  • 1,187
  • 1
  • 7
  • 21
13

This warning is due to the Transition component which is used in many of the material-ui components like Drawer, Tooltip, Snackbar etc.

Personally, I faced this warning in all of them, but only fixed this for the Snackbar component.

The solution is to create a ref and pass it into your root component. Then, manually forward the ref to your child components which use Transition.

Here is the code for the Snackbar component which fixed the issue for me. Since it's just a warning, probably ignore it. You don't need to remove StrictMode. It will be fixed in future material-ui releases.

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;
Animesh Jain
  • 131
  • 1
  • 2
  • Very helpful solution. Worked for me for the dialog as well. For me it was helpful to check out the default implementation on github to find out, what transision component is used by default. https://github.com/mui-org/material-ui/tree/next/packages/material-ui/src For Dialog the `TransitionComponent` is: `const DialogTransition = forwardRef((props: FadeProps, ref) => )` – Dave Gööck Aug 18 '21 at 18:57
  • just by adding const variableNameRef = createRef() in parent and passing a ref={variableNameRef} to a Dawer component removed the error for me. This led me to that solution, thank you. – Peter Koller Aug 20 '21 at 13:34
  • Drawer doesn't have a TransitionComponent prop. – joshkarges Apr 20 '23 at 01:05
  • Interesting. It actually _can_ take a TransitionComponent prop, but it's not in the DrawerProps type, so you have to pass it like {...({TransitionComponent: FadeOnEnterTransition} as any)} – joshkarges Apr 20 '23 at 02:09
4

change your theme configuration

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

to

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

Generates a theme that reduces the amount of warnings inside React.StrictMode like Warning: findDOMNode is deprecated in StrictMode.

WARNING: Do not use this method in production.

for production use import { createMuiTheme } from '@material-ui/core'; and replace StrictMode to Fragment.

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

to

ReactDOM.render(
  <React.Fragment>
    <App />
  </React.Fragment>,
  document.getElementById('root')
);
SaimumIslam27
  • 971
  • 1
  • 8
  • 14