[React] ThemeProvider로 다크모드 구현하기

Jinny·2023년 11월 22일
1

React

목록 보기
9/23
post-custom-banner

🖌️ Styled-Components 다크모드 구현

스타일 컴포넌트를 통해 다크모드를 구현할 때
ThemeProvider를 이용한다.

ThemeProvider

: Context API를 통해 모든 리액트 컴포넌트에게 테마를 제공한다. 자식 컴포넌트들이 깊게 있어도 제공된 테마를
접근할 수 있다.

예시)

import styled, { ThemeProvider } from 'styled-components'

const Box = styled.div`
  color: ${props => props.theme.color};
`

render(
  <ThemeProvider theme={{ color: 'mediumseagreen' }}>
    <Box>I'm mediumseagreen!</Box>
  </ThemeProvider>
)

ThemeProvider에 props로 theme를 전달하면 Provider로 감싸준 아래에 있는 모든 컴포넌트들이 스타일을 정의할 때 theme 값을 사용할 수 있다.

우선 다크모드,라이트모드를 구현하기 위해
배경 색상과 글씨 색상을 지정해준다.

📁 style 👉 theme.js


export const light = {
    color: 'black',
    backgroundColor: 'white'
};

export const dark = {
    color: 'white',
    backgroundColor: 'black'
};

export const theme = {
    light,
    dark
};

theme 변수 안에 라이트모드와 다크모드 객체를 포함시킨다.

App.js

다크모드를 적용할 때 토글 버튼이 필요하다.
초기값은 라이트모드이며 토글 버튼을 클릭하면 다크모드,
다시 클릭하면 라이트모드로 변해야 한다.

import { ThemeProvider } from 'styled-components';
import InnerComponent from './components/InnerComponent';
import { dark, light } from './style/theme'
import { useState } from 'react';
import InnerComponent2 from './components/InnerComponent2';
import GlobalStyle from './style/GlobalStyle';

function App() {
  const [darkMode, setDarkMode] = useState(false);
  const toggleDarkMode = () => {
    setDarkMode(mode => !mode);
  }

  return (
    <ThemeProvider theme={darkMode ? dark : light}>
      <GlobalStyle />
      <InnerComponent darkMode={darkMode} toggleDarkMode={toggleDarkMode} />
      <InnerComponent2 />
    </ThemeProvider>
  );
}

export default App;
  • theme는 다크모드 상태이면 dark로 설정한 객체를, 라이트 모드이면 light로 설정한 객체 값을 가진다.
  • 토글 버튼은 InnerComponent에서 제어하기 때문에 다크모드의 상태값과 토글하는 함수를 props로 전달한다.

📁style 👉 GlobalStyle.js

ThemeProvider를 통해 전역 스타일을 적용할 수 있다.
또한

import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
    *{
        box-sizing: border-box;
    }
    body{
        margin:0;
        font-size:16px;
        background-color: ${(props) => props.theme.backgroundColor};
        color:${(props) => props.theme.color};
    }
    button{
        border:none;
        outline:none;
        cursor: pointer;
    }
`;

export default GlobalStyle;
  • 다크모드이면 props.theme는 다크모드로 설정된 객체(dark), 라이트모드이면 props.theme는 라이트모드로 설정된 객체(light)를 접근할 수 있다.
post-custom-banner

0개의 댓글