0

I'm rewriting my little project to material-ui, and I'm using for this material-ui-next reactjs library; For one component withStyle decorator worked just fine, for the other it doesn't decorate component with styles and trows this error:

Uncaught TypeError: Cannot read property 'root' of undefined at Respondent.render (MuiRespondent.tsx:48) at vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:30228 at measureLifeCyclePerf (vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:29508) at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:30227) at ReactCompositeComponentWrapper._renderValidatedComponent (vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:30254) at ReactCompositeComponentWrapper.performInitialMount (vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:29794) at ReactCompositeComponentWrapper.mountComponent (vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:29690) at Object.mountComponent (vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:12868) at ReactCompositeComponentWrapper._updateRenderedComponent (vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:30197) at ReactCompositeComponentWrapper._performComponentUpdate (vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:30156)

Component which throws error:

import * as React from 'react';
import Button from 'material-ui/Button';
import Dialog, {
  DialogTitle,
  DialogContent,
  DialogContentText,
  DialogActions,
} from 'material-ui/Dialog';
import Typography from 'material-ui/Typography';
import withStyles, { WithStyles, StyleRulesCallback } from 'material-ui/styles/withStyles';
import { RouteComponentProps } from 'react-router';
import withRoot from '../../withRoot';

const styles: StyleRulesCallback<'root'> = theme => ({
  root: {
    textAlign: 'center',
    paddingTop: theme.spacing.unit * 20,
  },
});

type State = {
  open: boolean;
};

export class Respondent extends React.Component<WithStyles<'root'>, State> {
    constructor(props: any){
        super(props);

        this.state = {
            open: false,
          }
    };

  handleClose = () => {
    this.setState({
      open: false,
    });
  };

  handleClick = () => {
    this.setState({
      open: true,
    });
  };

  render() {
    return (
      <div className={this.props.classes.root}>
        <Dialog open={this.state.open} onClose={this.handleClose}>
          <DialogTitle>Super Secret Password</DialogTitle>
          <DialogContent>
            <DialogContentText>1-2-3-4-5</DialogContentText>
          </DialogContent>
          <DialogActions>
            <Button color="primary" onClick={this.handleClose}>
              OK
            </Button>
          </DialogActions>
        </Dialog>
        <Typography variant="display1" gutterBottom>
          Material-UI
        </Typography>
        <Typography variant="subheading" gutterBottom>
          example project
        </Typography>
        <Button variant="raised" color="secondary" onClick={this.handleClick}>
          Super Secret Password
        </Button>
      </div>
    );
  }
}

export default withRoot(withStyles(styles)<{}>(Respondent));

And here is my withRoot decorator:

import * as React from 'react';
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import * as colors from 'material-ui/colors';
import CssBaseline from 'material-ui/CssBaseline';

// A theme with custom primary and secondary color.
// It's optional.
const theme = createMuiTheme({
  palette: {
    primary: colors.lightBlue,
    secondary: colors.blueGrey,
  },
});

function withRoot(Component: React.ComponentType) {
  function WithRoot(props: object) {
    // MuiThemeProvider makes the theme available down the React tree
    // thanks to React context.
    return (
      <MuiThemeProvider theme={theme}>
        <div>
            {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
            <CssBaseline />
            <Component {...props} />
        </div>
      </MuiThemeProvider>
    );
  }

  return WithRoot;
}

export default withRoot;

Another component, for which withStyle decorator works, looks almost identical, I think I'm missing something obvious but can't see what

Ivan Sukhetskyi
  • 113
  • 2
  • 13
  • When exporting the composition, did you try to call `withStyles` before `withRoot`? – Emi Mar 29 '18 at 09:54
  • No, will try try, this actually make sense – Ivan Sukhetskyi Mar 29 '18 at 10:03
  • Still the same error message – Ivan Sukhetskyi Mar 29 '18 at 10:13
  • What about setting the styles directly in your `withRoot` HOC instead of in the Respondent component? Wouldn't it make more sense to put them directly there? – Emi Mar 29 '18 at 10:16
  • I'm not sure how to do it, can you provide an example, please? – Ivan Sukhetskyi Mar 29 '18 at 10:43
  • Something like this (in ES6): `const styles = theme => ({ root: { textAlign: 'center', paddingTop: theme.spacing.unit * 20, }, }); export function withRoot(WrappedComponent) { class Root extends React.Component { render() {
    {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
    } } return withStyles(styles)(Root); }`
    – Emi Mar 30 '18 at 21:55
  • 1
    I've figured this, here is the [code](https://github.com/isukhetskyi/bifrost/tree/materialui/src/Bifrost.UI), but thanks for help anyway – Ivan Sukhetskyi Apr 02 '18 at 08:28

0 Answers0