Migration MUI v4 to v5 makeStyles 사용하기

이경은·2021년 12월 15일
0

문제점

  • 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>
  );
};
  • 번거로워 보일 수 있지만 공식 문서에서 추천하는 대로 바꾸는 것보다는 덜 번거로운 것 같다.
profile
Web Developer

0개의 댓글