classes vs styles for CSS className in Reactjs

Viewed 4513

In the below code, why does a call to the classes object work? It seems like the call should be to the styles object defined as a const up top.

For example, in this demo:

className={classes.button}

works as written. But it seems like it should be

className={styles.button}

Is there any actual classes object defined anywhere? If so, where is it defined? The markup implies a this.props.classes object. But there are no props passed to <Demo /> when called in index.js.

What's going on here?

https://codesandbox.io/s/qxv466wlq
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';

const styles = theme => ({
  button: {
    margin: theme.spacing.unit,
  },
  input: {
    display: 'none',
  },
});

function OutlinedButtons(props) {
  const { classes } = props;
  return (
    <div>
      <Button variant="outlined" className={classes.button}>
        Default
      </Button>
      <Button variant="outlined" color="primary" className={classes.button}>
        Primary
      </Button>
      <Button variant="outlined" color="secondary" className={classes.button}>
        Secondary
      </Button>
      <Button variant="outlined" disabled className={classes.button}>
        Disabled
      </Button>
      <Button variant="outlined" href="#outlined-buttons" className={classes.button}>
        Link
      </Button>
      <input
        accept="image/*"
        className={classes.input}
        id="outlined-button-file"
        multiple
        type="file"
      />
      <label htmlFor="outlined-button-file">
        <Button variant="outlined" component="span" className={classes.button}>
          Upload
        </Button>
      </label>
    </div>
  );
}

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

export default withStyles(styles)(OutlinedButtons);
1 Answers

If you look at this line:

export default withStyles(styles)(OutlinedButtons);

the answer to your question is provided I believe. Material UI has a function withStyles that takes a styles object, and then returns another function that takes a component to return a new component. This is a Higher Order Component, and can be read about on the React docs.

If you look at the linked code of withStyles, you can see the following line where it renders the passed in component:

return <Component {...more} classes={this.getClasses()} ref={innerRef} />;

And is providing the classes prop, making it available to any component exported with withStyles.

Related