question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Hot Module Replacement with MuiThemeProvider always errors

See original GitHub issue
  • I have searched the issues of this repository and believe that this is not a duplicate.

Possibly related: https://github.com/mui-org/material-ui/issues/8353 https://github.com/mui-org/material-ui/issues/8878

Expected Behavior

Whenever I change a value in my const styles = theme => ({…}) in Drawer (or anything else in the application), material-ui withStyles should not throw an error.

Current Behavior

Anytime I change a value in my styles definition (or anything for that matter), after a hot module replacement, the following error occurs. The UI still updates as expected, but the errors start stacking up.

Uncaught TypeError: Cannot read property 'refs' of undefined
    at ProxyComponent.detach (withStyles.js:339)
    at ProxyComponent.detach (createPrototypeProxy.js:44)
    at ProxyComponent.<anonymous> (withStyles.js:251)
    at commitCallbacks (react-dom.development.js:6155)
    at commitLifeCycles (react-dom.development.js:8812)
    at commitAllLifeCycles (react-dom.development.js:9967)
    at HTMLUnknownElement.callCallback (react-dom.development.js:540)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:579)
    at invokeGuardedCallback (react-dom.development.js:436)
    at commitRoot (react-dom.development.js:10071)
react-dom.development.js:9769 The above error occurred in the <withStyles(ResponsiveDrawer)> component:
    in withStyles(ResponsiveDrawer) (created by App)
    in MuiThemeProvider (created by MuiThemeProviderWrapper)
    in MuiThemeProviderWrapper (created by App)
    in App
    in Router (created by ConnectedRouter)
    in ConnectedRouter
    in Provider
    in AppContainer
Cannot read property 'refs' of undefined
    at ProxyComponent.detach (withStyles.js:339)
    at ProxyComponent.detach (createPrototypeProxy.js:44)
    at ProxyComponent.<anonymous> (withStyles.js:251)
    at commitCallbacks (react-dom.development.js:6155)
    at commitLifeCycles (react-dom.development.js:8812)
    at commitAllLifeCycles (react-dom.development.js:9967)
    at HTMLUnknownElement.callCallback (react-dom.development.js:540)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:579)
    at invokeGuardedCallback (react-dom.development.js:436)
    at commitRoot (react-dom.development.js:10071)

Steps to Reproduce (for bugs)

Unfortunately this is a HMR issue, and I can’t workup a codesandbox.io example. Here is my relevant setup (maybe I am doing something wrong?)

Steps

  1. Build / Run
  2. Modify any part of app under the hot.module.accept (styles, content, etc…)
  3. Error occurs but UI updates OK (the UI still updates fine - but the error is still thrown)

App.js

import React from 'react';
import ReactDOM from 'react-dom';
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import purple from 'material-ui/colors/purple';
import blue from 'material-ui/colors/blue';
import green from 'material-ui/colors/green';
import red from 'material-ui/colors/red';

import Drawer from '../Drawer';
import DevTools from '../DevTools';

const theme = createMuiTheme({
  palette: {
    primary: green, // Purple and green play nicely together.
    secondary: {
      ...green,
      A400: '#00e677',
    },
    error: red,
  },
  overrides: {
    MuiDrawer: {
      docked: {
        flex: '0 0 auto',
        height: '100%'
      }
    }
  }
});

class App extends React.Component {
  render() {
    return (
        <MuiThemeProvider theme={theme}>
          <Drawer />
        </MuiThemeProvider>
    );
  }
}
export default App;

Drawer.js

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Drawer from 'material-ui/Drawer';
import AppBar from 'material-ui/AppBar';
import Toolbar from 'material-ui/Toolbar';
import List from 'material-ui/List';
import Typography from 'material-ui/Typography';
import IconButton from 'material-ui/IconButton';
import Hidden from 'material-ui/Hidden';
import Divider from 'material-ui/Divider';
import MenuIcon from 'material-ui-icons/Menu';
import Grid from 'material-ui/Grid';
import Paper from 'material-ui/Paper';
import { mailFolderListItems, otherMailFolderListItems } from './tileData';

const drawerWidth = 240;

const styles = theme => ({
  root: {
    width: '100%',
    marginTop: 4,
    zIndex: 1,
    height: '100%',
    overflow: 'hidden',
  },
  appFrame: {
    position: 'relative',
    display: 'flex',
    width: '100%',
    height: '100%',
  },
  appBar: {
    position: 'absolute',
    marginLeft: drawerWidth,
    [theme.breakpoints.up('md')]: {
      width: `calc(100% - ${drawerWidth}px)`,
    },
  },
  navIconHide: {
    [theme.breakpoints.up('md')]: {
      display: 'none',
    },
  },
  drawerHeader: theme.mixins.toolbar,
  drawerPaper: {
    width: 250,
    height: '100%',
    [theme.breakpoints.up('md')]: {
      width: drawerWidth,
      position: 'relative',
      height: '100%',
    },
  },
  content: {
    backgroundColor: theme.palette.background.default,
    width: '100%',
    padding: theme.spacing.unit * 3, 
    height: 'calc(100% - 56px)',
    marginTop: 56,
    [theme.breakpoints.up('sm')]: {
      height: 'calc(100% - 64px)',
      marginTop: 64,
    },
  },
  gridRoot: {
    flexGrow: 1
  },
  gridPaper: {
    padding: theme.spacing.unit * 2,
    height: '100%'
  },
  docked: {
    height: '100%'
  }
});

class ResponsiveDrawer extends React.Component {
  state = {
    mobileOpen: false,
  };

  handleDrawerToggle = () => {
    this.setState({ mobileOpen: !this.state.mobileOpen });
  };

  render() {
    const { classes, theme } = this.props;

    const drawer = (
      <div>
        <div className={classes.drawerHeader} />
        <Divider />
        <List>{mailFolderListItems}</List>
        <Divider />
        <List>{otherMailFolderListItems}</List>
      </div>
    );

    return (
      <div className={classes.root}>
        <div className={classes.appFrame}>
          <AppBar className={classes.appBar}>
            <Toolbar>
              <IconButton
                color="contrast"
                aria-label="open drawer"
                onClick={this.handleDrawerToggle}
                className={classes.navIconHide}
              >
                <MenuIcon />
              </IconButton>
              <Typography type="title" color="inherit" noWrap>
                Responsive drawer
              </Typography>
            </Toolbar>
          </AppBar>
          
          <Hidden mdUp>
            <Drawer
              type="temporary"
              anchor={theme.direction === 'rtl' ? 'right' : 'left'}
              open={this.state.mobileOpen}
              classes={{
                paper: classes.drawerPaper,
              }}
              onRequestClose={this.handleDrawerToggle}
              ModalProps={{
                keepMounted: true, // Better open performance on mobile.
              }}
            >
              {drawer}
            </Drawer>
          </Hidden>
          <Hidden mdDown implementation="css">
            <Drawer
              type="permanent"
              open
              classes={{
                docked: classes.docked,
                paper: classes.drawerPaper,
              }}
            >
              {drawer}
            </Drawer>
          </Hidden>
          <main className={classes.content}>
              <Grid container className={classes.gridRoot}>
                <Grid item xs={12}>
                  <Grid container alignItems='stretch'>
                    <Grid item key={1}>
                      <Paper className={classes.gridPaper}>
                        {'Content 1'}
                      </Paper>
                    </Grid>
                    <Grid item key={2}>
                      <Paper className={classes.gridPaper}>
                        {'Content 2'}
                      </Paper>
                    </Grid>
                    <Grid item key={3}>
                      <Paper className={classes.gridPaper}>
                        {'Content 3'}
                      </Paper>
                    </Grid>
                  </Grid>
                  
                </Grid>
              </Grid>
          </main>
        </div>
      </div>
    );
  }
}

ResponsiveDrawer.propTypes = {
  classes: PropTypes.object.isRequired,
  theme: PropTypes.object.isRequired,
};

export default withStyles(styles, { withTheme: true })(ResponsiveDrawer);

Context

If I remove MuiThemeProvider from App.js, all works as expected with the default theme.

Doing some debugging, it looks like this line, at some point returns undefined / null:

var sheetManagerTheme = sheetManager.get(theme) https://github.com/mui-org/material-ui/blob/023fee9092571e98814e64221015c6b669353fbe/src/styles/withStyles.js#L267

in the detach method.

Your Environment

Tech Version
Material-UI ^1.0.0-beta.21
React 16.0.0
browser Chrome latest

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:13 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
waynepancommented, Feb 2, 2018

Using react hot loader v4 (possibly 3), I think this can be solved by moving the MuiThemeProvider one level up. eg render( <MuiThemeProvider theme={theme}> <App /> </MuiThemeProvider>, document.getElementById('app'))

Then having <App /> be the hot reload root component.

2reactions
chaddjohnsoncommented, Dec 14, 2017

I changed

export default withStyles(styles, {withTheme: true})(Navigation);

to

export default withTheme()(withStyles(styles)(Navigation));

in my component wrapped by <MuiThemeProvider>, and now I just get a warning.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Hot Module Replacement with MuiThemeProvider always errors
Anytime I change a value in my styles definition (or anything for that matter), after a hot module replacement, the following error occurs....
Read more >
Uncaught Error: [HMR] Hot Module Replacement is disabled
Uncaught Error: [HMR] Hot Module Replacement is disabled. I have a few questions about this: My understanding of using Hot Module Replacement is ......
Read more >
HMR API - Vite
Vite exposes its manual HMR API via the special import.meta.hot object: ... module is non null // If the update was not succeful...
Read more >
React Material-UI Cookbook - Open Directory Data Archive
You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own...
Read more >
React-Hot-Loader 4.6. ⚛️ — Hooks, Errors and ... - Medium
We just moved hot(module) inside /root, so HMR would be configured before the ... React-Hot-Loader was replacing render by it own version like...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found