Redux-toolkit DarkMode (w_ emotion)

Jaewoong2·2020년 11월 11일
2

Redux

목록 보기
4/5
post-custom-banner

Emotion 과 Redux를 이용한 React DarkMode를 구현할 예제 입니다

Emotion

이모션이란, CSS in JS 형식으로, Javascript 파일 안에서 CSS를 설정할 수 있는 라이브러리 입니다. 왜 이걸 하냐면, React의 경우 자바스크립트로 (코드, CSS, HTML) 모든 것을 한번에 하는 것이 이상적인데 Html 태그안에 넣어서 css를 지정하는 in-line css를 사용하면 리랜더링 될 때마다 다시 새롭게 메모리를 쓰는데, 이모션같은 라이브러리를 쓰면 그럴일이 없다는 사실..!

뭐 그외에도 변수사용이나, Props 사용 과 같은 상태 에 따른 css를 쉽게 해주기 때문에 사용 된다.

Emotion 설정 및 사용

타입스크립트와 이모션을 사용할 때 한가지 주의할 점이 있는데, emotion-theming 기능을 사용하며 Emotion/styled 를 사용할때 styled 내부안에서 color : ${props => props.theme.textColor} 을 하게 되면 textColor를 못 찾아서 오류가 뜨게 된다. 그 이유는 styledprops.theme 의 타입이 object 로만 되어 있어서 theme.something 을 못찾게 되는 것이다. 그래서 그 type을 바꿔주면 되는데, 공식문서를 찾아가서 바꾸는 게 이 방법이다.

import styled, { CreateStyled } from '@emotion/styled'

export type themeType = {
   	...
    color : string;
    background : string;
    textColor : string;   
    boxShadow : string;
    darkMode : boolean;
  	...
}

export default styled as CreateStyled<themeType>

쓰고 싶은 타입을 재 지정해서 export 해서 이것을 emotion/styled 대신에 쓰는 방법이다.

아마 emotion/styled 을 사용하지 않고 다른 방법으로 emotion 을 쓰면 이러한 오류는 안나오는 것으로 알고 있다.

뭐 이런 저런 사용법은 건너뛰고 ThemeProvider를 이용한 테마기능을 사용해보자.

Emotion-theming

// ThemeProviderContainer.tsx

import { ThemeProvider } from 'emotion-theming'

  ...


const theme = {
  color : isDarkMode ? black : white,
  background : isDarkMode ? "rgba(20, 20, 20, 0.7)" : "rgba(230, 230, 230)",
  textColor : isDarkMode ? white : black,
  boxShadow : isDarkMode ? 'rgba(230, 230, 230, 0.3)' :'rgba(20, 20, 20, 0.3)',
  darkMode : isDarkMode
}

  ...

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

이렇게 하면 하위 컴포넌트에 theme이 전달이 된다.

하위 컴포넌트에서는 그냥

const Main = styled.main`
  width : 100vw;
  height : 100vh;
  font-family : sans-serif;
  background-color :${props => props.theme.background};  
  color :${props => props.theme.textColor};

${props.theme} 의 형식으로 찾아다니면 된다


타입을 새로 지정해서 보내준 것이 바로 뜬다.

또한, useTheme() 함수가 제공되는데 이 함수는 ThemeProvidertheme으로 받은 것을 전역상태로 관리 할 수 있는 것 이다.

const theme = useTheme() as any;

타입을 지정해주지 않으면 unknown 타입인데, 이러면 theme 객체를 사용하면 오류가 뜬다. theme.color // 오류 발생
theme 은 전역상태이기 떄문에 이것을 받아 컴포넌트 여기저기 상태를 바꿔주면 된다.


LocalStroage

로컬스토리지에 key : dark, value : {value : boolean } 을 넣어줄 것이다.

  1. ThemeProvider 에서는 JSON.parse(localstorage.getItem('dark')).value 를 해서 정보를 받는다.
  2. 토글을 누를 때마다 localstorage.setItem('dark', JSON.stringify({ value : !theme.darkMode })) 를 해준다.
profile
DFF (Development For Fun)
post-custom-banner

1개의 댓글

comment-user-thumbnail
2021년 10월 6일

useTheme사용할 때 emotion.d.ts파일로 theme타입을 declare moudle사용해서 재정의 해주면 사용가능해져요!

답글 달기