Material-UI Theme에 대해 알아보자

2021. 7. 3. 17:30프로그래밍/React.js

728x90

나는 Material-UI를 좋아한다.

왜냐면 나는 디자인을 더럽게 못해서 깔끔하고 보기 좋은 템플릿으로 쓰기 좋다.

근데 맨날 makeStyles, useTheme등을 쓰기만 하지 원리는 몰랐다.

그런데 이번 기회에 Hook을 공부한 다음에 보니, 이해가 되기 시작했다.


Theme란 무엇일까?

뭐긴 뭐야. 아무것도 아니다. 그냥 하나의 한낱 object일 뿐이다.

그런데 우리가 이 object에 theme라는 이름을 불러주면, 그는 우리에게 와서 암튼 그렇게 된다.

그냥 object안에 몇가지 키워드를 넣어서, context에 넣는다.
그 다음에 Hook을 사용해서 꺼내먹는(?) 방식이다.

이 Theme에는 공통으로 사용하는 스타일 내용을 적는다.
다만, styles와 theme의 차이점은, theme는 규칙성에 가깝다.

예를 들어 리스트 사이의 거리를 '한 칸'을 둔다고 하면, 이 '한 칸'은 theme다.
그런데 한 칸당 10px씩 띄운다고 하면, 이건 styles이다.


그래서 Theme를 어떻게 쓸까?

원리를 알아보며 순서대로 알아보자.

1. ThemeProvider를 트리 최상단에 넣는다

function App() {
  return (
    <SomeComponent />
  );
}

||
\/

import { ThemeProvider } from '@material-ui/core/styles';

const theme = {};

function App() {
  return (
    <ThemeProvider theme={theme}>
      <SomeComponent />
    </ThemeProvider>
  );
}

ThemeProvider은 built-in context, 즉 React.createContext를 이용해 만든 컨텍스트다.

이 컨텍스트를 Tree최상단을 감싸도록(Wrap)한다.

그러면 전체에 ContextConsumer에 감싸진 부분은 props에 theme가 들어가게 된다.


2-1. useTheme를 이용하여 theme가져오기

위에서 지정한 theme를 Hook을 이용하여 가져오는 방법이다.

우리가 ThemeProvider에 theme를 전달하면, 시스템에 theme정보가 저장이 된다.

이 theme정보를 Hook을 이용해 가져오는 것이다.

import { useTheme } from '@material-ui/core/styles';

export default function MyComponent() {
  const theme = useTheme();

  return <div>{`spacing ${theme.spacing}`}</div>;
}

2-2. withTheme를 이용해서 props로 theme전달 받기.

두번째 방법은 HOC를 이용하여 props로 theme를 받는 방법이다.

HOC는 고차원 컴포넌트로, 컴포넌트를 다른 컴포턴트로 감싸는 디자인 패턴이다.

우리가 해줄 일은, export해줄 때 withTheme로 컴포넌트를 감싸주면 된다.

import { withTheme } from '@material-ui/core/styles';

function MyComponent(props) {
  return <div>{props.theme.direction}</div>;
}

export default withTheme(MyComponent);

보다시피 MyComponent를 withTheme로 감쌌는데,
다른 컴포넌트에서 이 MyComponent를 import하면 다음과 같은 형태가 된다.

// 우리가 호출한 것
import MyComponent from './MyComponent';

const A = () => {
  return (
    <div>
      <MyComponent />
    </div>
  )
}

// 실제 Tree
<div>
  <ThemeContextConsumer>
    <MyComponent theme={theme} />
  </ThemeContextConsumer>
</div>

이런 구조가 되기 때문에, MyComponent는 ThemeContextConsumer로부터 'theme'를 props로 전달 받는다.

'프로그래밍 > React.js' 카테고리의 다른 글

React - HOC 대신 useContext를 사용해보자.  (0) 2021.07.07
React Router 배워보기  (0) 2021.07.04
React Hook에 대한 탐구  (0) 2021.07.03
React - Should have a queue.  (0) 2021.07.03
Javascript - prototype이란?  (0) 2021.05.31