티스토리 뷰

개발

[React] ThemeProvider 알아보기

Dev.JH 2023. 8. 23. 23:05

사이드 프로젝트를 진행하면서 다크모드를 위해 ThemeProvider를 사용할 일이 생겼다. 처음 접한 건 1년 좀 넘었는데 다시 한 번 되새겨보고자 포스팅을 남긴다. 
스타일을 관리하고 전역적인 테마를 설정하는데 도움을 주는 ThemeProvider에 대해서 알아보는 시간을 가지도록 해보자!

🤷‍♂️왜 ThemeProvider?

다크모드를 개발하기에 앞서 어떻게 접근해야할지 생각해보는 시간을 가져보자.

const Container = styled.div<{mode: boolean}>`
  background-color: ${(props) => props.mode ? "#000000" : "#ffffff"};
`

방법 중 하나로  위와 같이 props로 전달 받은 mode를 기준으로 true면 검정색, false면 흰색으로 배경색을 지정해줄 수 있겠다.

그런데 props로 전달해줘야하는 컴포넌트들이 100개가 넘어간다고 가정해보자. 생각만해도 골치가 아프다.

혹은 디자이너가 '배경이 너무 어두운 느낌이라 값을 #464545로 바꿔주세요.' 라고 한다면? 100개가 넘어가는 컴포넌트들에 대해서 노가다를 열심히 해주면 되겠다. 그러나 우리는 그런 일은 일어나지 않았음 할 것이다. 그렇다면 ThemeProvider가 이 문제들을 해결해 줄 수 있을까?

답은 '그렇다'이다.

 

👍ThemeProvider의 장점

  • 일관된 디자인: 모든 컴포넌트에서 동일한 색상, 폰트, 간격 등의 스타일을 사용하므로 디자인에 일관성이 생긴다.
  • 테마 관리 용이성: 테마를 한 곳에서 관리하므로 테마가 변경되거나 업데이트 되어야할 필요가 생기면 한 곳에서만 수정하면 된다. 따라서 여러 컴포넌트를 일일이 수정할 필요가 없어져 유지보수가 용이해진다.
  • 컴포넌트 간 상태 공유: 사용자 설정에 따라 테마를 변경하고 모든 하위 컴포넌트에 적용할 수 있다.

 

⭐ThemeProvider 사용법

나는 프로젝트에서 상단에 있는 로고를 클릭하였을 때, 다크모드로 변경이 가능했어야 했다.

우선 theme.ts 파일을 만들어 안에 전역에서 사용되어질 변수들과 값을 세팅해주었다.

- theme.ts

export const lightTheme = {
    color:{
        fontColor: "black",
        bgColor: "white",
        navBorder: "#D9D9D9",
        chatBorder: "#D9D9D9" 
    }
}

export const darkTheme = {
    color:{
        fontColor: "white",
        bgColor: "#555A5F",
        navBorder: "black",
        chatBorder: "#D9D9D9"
    }
}

다음과 같이 파일을 작성했으면 이제 App.tsx 파일로 넘어가 보자.

 

- App.tsx

import { darkTheme, lightTheme } from './stlyes/theme';
import { ThemeProvider } from 'styled-components';

function App() {
  const [themeMode, setThemeMode] = useRecoilState(themeState);
  let theme = themeMode ? lightTheme : darkTheme;
  
  return (
      <ThemeProvider theme={theme}>	// 테마 지정
        <BrowserRouter>
        	// 생략
        </BrowserRouter>
      </ThemeProvider>
  );
}

 

방금 theme.ts 파일에서 만들었던 darkTheme, lightTheme를 import 해온다. 그리고 recoil을 사용하여 상태 변화에 맞춰 theme props에 전달해준다. 나와 같은 경우에는 themeModetrue면 라이트(일반) 테마를, false면 다크 테마를 props로 넘겨주도록  하였다.

const MainContainer = styled.div`
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  min-height: 100vh;
  background-color: ${props => props.theme.color.bgColor};
  color: ${props => props.theme.color.fontColor};
`;

그리고 앞서 만들었던 테마를 위와 같은 방식으로 컴포넌트에 적용할 수 있게 된다. 앞서 말했듯이 MainContainer의 하위 컴포넌트들은 따로 색이나 테마를 지정해주지 않은 이상, 상위컴포넌트인 MainConatiner와 같은 테마가 적용될 것이다.

 

 

✌️결과

마우스 포인터가 안보인다ㅠ

결과는 로고를 클릭할 때마다 다크모드 -> 라이트모드, 라이트모드 -> 다크모드로 변경되는 것을 확인 할 수 있다.

 

다크모드 구현 끝!

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31