global로 사용하는 stylesheet를 HOC패턴의 withStyles를 이용하여 사용하고 있는 상황에서 우리만의 custom theme을 적용하고 싶은 경우.
withStyles의 두번째 Argumets로는 options 값을 줄 수 있다.
옵션을 주고 나면, props에 추가된 theme을 이용하여 theme을 사용할 수 있다.
import React from 'react'
import { withStyles } from '@material-ui/core/styles;
import { styleSheet } from './stylesheet
class ExampleComponent extends React.Component {
...
render() {
const { theme } = this.props
return (
<button style={{ color: theme.palette.primary[100] }} >예제</button>
)
}
}
export default withStyles(styleSheet, { withTheme: true})(ExampleComponent)
이제 custom Theme을 사용할 준비가 되었다.
사용만 하면 될 것같은데 뭔 이슈가 있을까 싶기도 하지만, 예외는 늘 존재하기 마련이다.
HTMLElement에 직접 style을 줄 때 theme에 있는 스타일 객체를 같이 적용해야하는 상황이 이때다. (흔한 일은 아닐 것 같다..)
아무 생각 없이, react jsx에서 보이듯 style에 객체가 들어가니(얘는 props이건만...) HTMLelement.style도 객체겠거니 막연하게 생각한게 이 실수의 시작이었다. style.color
같이 property에 값을 지정할 수도 있어서 아무 의심도 없이 그렇게 생각했던 것이다.
const { theme } = this.props;
const span = document.createElement('span');
span.style = {
...span.style,
...theme.typography.body
}
여기서의 패착은 element.style의 타입을 전혀 생각하지 않았다는 점이다.
일단 적용이 안되는 시점에서야 document를 찾아보기 시작했는데, HTMLElement.style을 설정하는 방법은 아래와 같다.
span.style.cssText = "color: red; font-size: 14px";
//또는
span.setAttribute("style", "color:red; font-size: 14px")
즉 string이 들어가는 것인데, 여기서 또 멘붕이 오는 것이다.
내가 원하는건 material-ui custom Theme으로 만든 스타일 객체를 적용하는 것인데, 이걸 css 문법으로 바꿔야하는 것인가라는 생각에서 였는데, 의외로 그렇게 어렵지 않게 해결이 가능하다.
Object.assign(span.style, theme.typography.body);
span.style.fontWeight = 500;
...
이렇게 쓰면, 적용이 된다. 유의할 점은 style에 적용하는 것이기 때문에 inline style로 적용이 되는 부분인데, 이점 참고하여 사용하는 것이 좋을 것 같다.