makeStyles
를 사용하여 컴포넌트에 스타일 적용하기
React 컴포넌트에 Material UI로 스타일을 적용하기 위해 makeStyles
함수를 사용하는 것을 알 수 있습니다. 이 함수는 Material UI 테마를 사용하여 컴포넌트에 사용자 정의 스타일을 생성할 수 있는 강력한 도구입니다. 그러나 라이프사이클 메서드를 사용하는 클래스 컴포넌트를 사용할 경우, makeStyles
를 사용하려고 할 때 오류가 발생할 수 있습니다. 이 블로그 포스트에서는 이 제한을 극복하고 makeStyles
와 함께 라이프사이클 메서드를 사용할 수 있는 다양한 접근 방법을 탐구해보겠습니다.
옵션 1: Higher-Order Component API 사용하기
이 문제를 해결하기 위한 한 가지 방법은 Material UI에서 제공하는 Higher-Order Component (HOC) API를 사용하는 것입니다. makeStyles
훅 대신, withStyles
함수를 사용하여 Higher-Order Component를 생성할 수 있습니다. 다음은 예시입니다:
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}>이 컴포넌트는 HOC에 전달됩니다</Button>
);
}
}
HigherOrderComponentUsageExample.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(HigherOrderComponentUsageExample);
옵션 2: 훅과 함께 함수형 컴포넌트 사용하기
클래스 컴포넌트를 함수형 컴포넌트로 변환하는 것이 가능하다면, 고려할 만합니다. React Hooks의 도입을 통해 makeStyles
훅과 라이프사이클 메서드를 동일한 컴포넌트에서 사용할 수 있습니다. 다음은 예시입니다:
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;
옵션 3: 오버라이딩된 테마를 사용하는 클래스 컴포넌트
다른 접근 방법과 비교하여 더 많은 유연성을 제공하는 방법은 기본 Material UI 테마 속성을 MuiThemeProvider
를 사용하여 오버라이딩하는 것입니다. 이를 통해 부모 컴포넌트 내에서 여러 개의 MuiThemeProvider
인스턴스를 사용할 수 있습니다. 다음은 예시입니다:
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}>고차 컴포넌트</Button>
</MuiThemeProvider>
);
}
}
HigherOrderComponent.propTypes = {
classes: PropTypes.object.isRequired,
};
export default HigherOrderComponent;
이 세 가지 옵션 중 하나를 따라하면, Material UI에서 makeStyles
를 사용하여 컴포넌트에 효과적으로 스타일을 적용하면서도 라이프사이클 메서드를 사용할 수 있습니다. 프로젝트 요구 사항에 가장 적합한 방법을 선택하고, Material UI가 제공하는 유연성과 사용자 정의 옵션을 즐기십시오!