문제점
- MUI 공식 문서를 보고 Migration 과정을 실행했으나 세부 코드는 바뀌지 않음
- makeStyles는 사용할 수는 있지만, lagacy라고 표현하며 다른 방법을 권함.
- 하지만 하나 하나 바꾸기에는 너무 많고 힘들다는 판단.
- 아래 사진은 makeStyles 코드를 v5에 맞춰서 변경하는 방법으로 공식 문서에서 권장하는 방법이다.
- 구글링 해보니 custom hook을 사용해서 기존 makeStyles 코드를 살릴 수 있는 방법 발견
참조한 블로그 주소
해결
1) Custom Hook 만들기
- react 프로젝트에서 src 폴더 아래에 hooks라는 폴더를 만들고, useClasses.js 파일 생성
- 아래의 코드 붙여넣기
- @emotion/css 와 @emotion/react 라는 라이브러리도 설치함.
import { useMemo } from "react";
import { css } from "@emotion/css";
import { useTheme } from "@emotion/react";
const useClasses = (stylesElement) => {
const theme = useTheme();
return useMemo(() => {
const rawClasses =
typeof stylesElement === "function" ? stylesElement(theme) : stylesElement;
const prepared = {};
Object.entries(rawClasses).forEach(([key, value = {}]) => {
prepared[key] = css(value);
});
return prepared;
}, [stylesElement, theme]);
};
export default useClasses;
2) 코드 수정
// 기존 코드
import clsx from 'clsx';
import { makeStyles, useTheme } from '@material-ui/styles';
const useStyles = makeStyles(theme => ({
root: {
paddingTop: 56,
[theme.breakpoints.up('sm')]: {
paddingTop: 64
}
},
shiftContent: {
paddingLeft: 240
},
content: {
minHeight: '85vh',
position: 'relative'
},
footer: {
position: 'absolute',
bottom: '0',
height: '2.5rem',
marginBottom: '-2rem',
width: '100%'
}
}));
const Main = props => {
...
const classes = useStyles();
...
return (
<div
className={clsx({
[classes.root]: true,
[classes.shiftContent]: isDesktop
})}
>
<Topbar onSidebarOpen={handleSidebarOpen} />
<Sidebar
onClose={handleSidebarClose}
open={shouldOpenSidebar}
variant={isDesktop ? 'persistent' : 'temporary'}
/>
<main className={classes.content}>
{children}
<Footer className={classes.footer} />
</main>
</div>
);
};
- 크게 수정된 부분은 없다. makeStyles를 import 하는 대신에 useClasses hook을 import하고, styles에 makeStyles를 없애고, classes를 useClasses(styles)로 설정한다.
// 수정 코드
import clsx from "clsx";
import useClasses from "hooks/useClasses";
const styles = (theme) => ({
root: {
paddingTop: 56,
[theme.breakpoints.up("sm")]: {
paddingTop: 64
}
},
shiftContent: {
paddingLeft: 240
},
content: {
minHeight: "85vh",
position: "relative"
},
footer: {
position: "absolute",
bottom: "0",
height: "2.5rem",
marginBottom: "-2rem",
width: "100%"
}
});
const Main = (props) => {
const classes = useClasses(styles);
return (
<div
className={clsx({
[classes.root]: true,
[classes.shiftContent]: isDesktop
})}
>
<Topbar onSidebarOpen={handleSidebarOpen} />
<Sidebar
onClose={handleSidebarClose}
open={shouldOpenSidebar}
variant={isDesktop ? "persistent" : "temporary"}
/>
<main className={classes.content}>
{children}
<Footer className={classes.footer} />
</main>
</div>
);
};
- 번거로워 보일 수 있지만 공식 문서에서 추천하는 대로 바꾸는 것보다는 덜 번거로운 것 같다.