MUI v5는 Emotion을 기본 스타일 엔진으로 사용하고 있다. MUI의 기본 스타일 구성요소를 사용할때는 꽤나 잘 적용되기 때문에 일관적인 스타일링을 구성할때 유용하다.
다만, v5로 변경되면서 아직 최적화가 제대로 되지 않은 것인 스타일 API를 사용할때 특정사례에서 에러가 생길 수 있다. 하여, mui v5에서는 커스텀 컴포넌트를 구성할때 sx
프랍을 사용해서 커스텀할 것을 권고하고 있다.
진행하고 있는 프로젝트에서는 mui v5를 사용하고 있지만, 몇 구간에서는 emotion 스타일 엔진에서 제공하고 있는 styled
API를 이용하고 있는데, 이곳에서 쉽게 이해할 수 없는 에러가 발생했다.
일반적으로 JS에서 prop을 네이밍할때, 카멜케이스를 적용해서 네이밍을 한다. 이전에 리액트로 프로젝트를 구성할때는 아무런 문제가 없는 부분이었는데 이번 프로젝트에서는 유독 몇 구간에서 이러한 에러가 발생했다.
import { Swiper } from 'swiper/react';
import { styled } from '@mui/system';
export const Banner = styled('div') ((props) => ({
backgroundImage: `url(${props.bgImgUrl})`,
...
...(props.isTopBanner
? {
height: '100%',
}
: {
height: '172px',
marginRight: '20px',
borderRadius: '7px',
}),
}));
에러의 발생 구간을 살펴보았더니, styled
API를 사용해서 스타일드 컴포넌트를 구성하고 있는 곳에서 에러가 발생하고 있다. 컴포넌트의 props를 통해 선택적으로 스타일링을 구사하는 부분에서 문제가 생기고 있는데, 이에 관해서 mui 이슈란에서 활발히 논의가 되고 있는 것을 확인할 수 있었다.
mui 깃헙 관련 이슈 살펴보기
mui 깃헙 SSR in makeStyle 이슈 살펴보기
두 번째 링크는 서버사이드 랜더링에서 makeStyle을 적용했을때 className이 제대로 매치되지 않아 생기는 에러에 관해서 토론을 나누는 거인데, 결국 두 링크 모두 mui v4에서 mui v5로 버전업 되면서 생겨난 문제라는 공통점을 가진다.
다시 말하지만 mui v5는 이모션 스타일 엔진을 사용하고 있다. 하여, 스타일드 컴포넌트의 방식을 사용한 구간에서 여러 에러가 발생하고 있고 현재에도 다양한 논의가 진행 중에 있다.
라는 유저의 불만섞인 코맨트도 살펴볼 수 있었다.
이게 관해 mui 측에서는 withConfig
만 추가해주면 되고, 사용하는제 아무 문제가 없다고 답변을 남기고 있다. (하지만, 실제로 사용해보면 전혀 그렇지 않은걸..?)
프로젝트에서 사용하고 있는 코드도 mui v5에서 제안하고 있는대로 프랍을 파라미터로 전달해서 사용하고 있다. 하지만, props의 카멜 케이스 네이밍에서 경고가 발생하고 있다.
mui에서는 이를 의식해 몇 가지 해결책을 제시하고 있는데, theme
을 사용하거나, sx프랍을 사용해서 커스텀할 것, 마지막으로 shoudForwarProp
옵션을 설정하는 것이다.
options.shouldForwardProp ((prop: string) => bool [optional]): Indicates whether the prop should be forwarded to the Component.
shoudForwarProp
은 프랍을 컴포넌트의 구성 요소로 지정할 것인지에 대해 true와 false를 지정할 수 있다.
커스텀 theme에서 지정된 sx, color, variant의 값이 스타일드 div에 전파되지 않고, 바탕색과 패딩이 커스텀 값으로 생성된 것을 확인할 수 있다.
이 문제를 해결하기 위해 팀장님께서 제시해주신 방법은 shoudForwarProp
값에 false를 줘서 props을 전달할대 생기는 에러를 차단하는 것이었다.
export const Banner = styled("div", { shouldForwardProp: false })((props) => ({
backgroundImage: `url(${props.bgImgUrl})`,
/ ... /
...(props.isTopBanner
? {
height: "100%",
}
: {
height: "172px",
marginRight: "20px",
borderRadius: "7px",
}),
}));
이렇게 코드를 수정하고 나니 더 이상 콘솔창에 경고가 발생하지 않았다.
사실 이 경고창이 콘솔에 발생하더라도, 기능 구현에는 아무런 영향이 없었다. 때문에, 무시하고 넘어갈 수도 있었지만, 몇 가지 프랍만으로도 콘솔창을 경고가 가득 채우다보니 개발 효율이 떨어지는 것을 느낄 수 있었다.
이 에러를 수정하는데 꽤나 고생을 해야 했지만, mui v5에서 겪을 수 있는 이슈에 대해서 보다 잘 이해하게 되었다. 꽤 흔하게 발생하는 이슈임에도 불구하고 명쾌하게 해결책을 제시하는 글을 찾아볼 수 없었기 때문에 이 포스팅을 남긴다.
반드시 누군가에게 큰 도움이 되었으면 좋겠다.