How to Style Components Using makeStyles and Still Have Lifecycle Methods in Material UI
If you’ve been working with Material UI for styling your React components, you might have come across the makeStyles
function. It’s a powerful tool that allows you to create custom styles for your components using the Material UI theme. However, if you’re using class components with lifecycle methods, you might encounter an error when trying to use makeStyles
. In this blog post, we’ll explore different approaches to overcome this limitation and still have the ability to use lifecycle methods alongside makeStyles
.
Option 1: Using Higher-Order Component API
One way to solve this issue is by using the Higher-Order Component (HOC) API provided by Material UI. Instead of using the makeStyles
hook, you can create a Higher-Order Component using the withStyles
function. Here’s an example:
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 => ({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
});
class HigherOrderComponentUsageExample extends React.Component {
render(){
const { classes } = this.props;
return (
<Button className={classes.root}>This component is passed to an HOC</Button>
);
}
}
HigherOrderComponentUsageExample.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(HigherOrderComponentUsageExample);
Option 2: Using Functional Components with Hooks
If converting your class component to a functional component is an option for you, it’s worth considering. With the introduction of React Hooks, you can use the makeStyles
hook and lifecycle methods within the same component. Here’s an example:
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Redirect } from 'react-router-dom';
import { Container, makeStyles } from '@material-ui/core';
import LogoButtonCard from '../molecules/Cards/LogoButtonCard';
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: theme.spacing(1)
},
highlight: {
backgroundColor: 'red',
}
}));
const Welcome = ({ highlight }) => {
const [userName, setUserName] = useState('');
const [isAuthenticated, setIsAuthenticated] = useState(true);
const classes = useStyles();
useEffect(() => {
axios.get('example.com/api/username/12')
.then(res => setUserName(res.userName));
}, []);
if (!isAuthenticated()) {
return <Redirect to="/" />;
}
return (
<Container maxWidth={false} className={highlight ? classes.highlight : classes.root}>
<LogoButtonCard
buttonText="Enter"
headerText={isAuthenticated && `Welcome, ${userName}`}
buttonAction={login}
/>
</Container>
);
}
export default Welcome;
Option 3: Class Component with Overridden Theme
Another approach is to override the default Material UI theme properties with the MuiThemeProvider
. This gives you more flexibility in comparison to other methods and allows you to use multiple MuiThemeProvider
instances within your parent component. Here’s an example:
import React from 'react';
import PropTypes from 'prop-types';
import Button from '@material-ui/core/Button';
import { MuiThemeProvider } from '@material-ui/core/styles';
import { createMuiTheme } from '@material-ui/core/styles';
const InputTheme = createMuiTheme({
overrides: {
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
}
});
class HigherOrderComponent extends React.Component {
render(){
const { classes } = this.props;
return (
<MuiThemeProvider theme={InputTheme}>
<Button className={classes.root}>Higher-order component</Button>
</MuiThemeProvider>
);
}
}
HigherOrderComponent.propTypes = {
classes: PropTypes.object.isRequired,
};
export default HigherOrderComponent;
By following one of these options, you can effectively style your components using makeStyles
while still having the ability to use lifecycle methods in Material UI. Choose the approach that best fits your project’s requirements and enjoy the flexibility and customization options that Material UI offers!