본문 바로가기

프론트엔드/ReactJS 마스터

[React] Typescript+styled coponents+theme으로 다크모드/라이트모드 만들기

이전 포스팅에서 Theme을 통해 다크모드와 라이트모드를 50%정도 완성해봤습니다. 

[React] styled component - Themes (tistory.com)

 

[React] styled component - Themes

theme을 사용해서 darkmode와 lightmode를 적용해보겠습니다. theme이란? 여러가지 색상들을 가지고 있는 object입니다. - theme 실행 방법 1) theme을 실행하기 위해서 index.js 파일에서 ThemeProvider import 하기! 2)

hyerilog.tistory.com

 

이번에는 theme(테마)을 타입스크립트와 연결해보겠습니다.

theme를 활용할 때는 실수할 확률이 높은데 타입스크립트로 theme를 사용한다면 실수를 미리 방지할 수 있습니다.

 

- typescript와 theme  연결하기

1) 타입스크립트에게 styled-component 알려주기

npm install @types/styled-components

#타입스크립트에게 styled-components가 무엇인지 설명해줍니다.

2) 확장자가 d.ts인 declaration(선언) 파일 만들기

이미 우리의 컴퓨터에는 index.d.ts파일이 있지만 테마(theme)를 활용해야하기 때문에 index.d.ts 파일을 확장할 필요가 있습니다. 따라서 styled.d.ts 파일을 생성하겠습니다. 이 파일은 이전에 설치해놓은 파일을 덮어쓰게 됩니다.

- styled.d.ts ->theme에 사용할 타입들 포함시키기

import 'styled-components';

// styled component의 Theme(테마) 정보를 확장시키기
declare module 'styled-components' {
    export interface DefaultTheme {
        // theme이 어떻게 보일지, theme의 속성들을 설명하는 부분
        // 우리가 사용할 theme(테마)
        textColor:string;
        bgColor:string;
    }
}

- themt.ts -> 테마만들기

테마는 styled.d.ts 파일에서 정의한 속성들하고 똑같아야합니다. 타입스크립트에게 theme의 형태를 알려주었으니 theme의 형태가 styled.d.ts와 똑같지 않으면 타입스크립트가 우리한테 실수를 말해줄겁니다.

import { DefaultTheme } from "styled-components";

export const lightTheme:DefaultTheme = {
    bgColor:"white",
    textColor:"black",
    btnColor: "tomato",
}
export const darkTheme = {
    bgColor:"black",
    textColor:"white",
    btnColor: "teal",
}

 

- index.tsx에 ThemeProvider 적용하기

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { ThemeProvider } from 'styled-components';
import { lightTheme } from './theme';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <ThemeProvider theme={lightTheme}>
       <App />
    </ThemeProvider>
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals

ThemeProvider는 styled-components로부터 오는 하나의 컴포넌트입니다. 이 ThemeProvider는 하나의 theme 오브젝트를 필요로 합니다. 그리고 어떤 컴포넌트를 ThemeProvider 컴포넌트 안에 넣게 된다면 그 모든 컴포넌트들은 Theme Object에 접근할 수 있게 됩니다.

- App.tsx -> 테마와 타입스크립트 연결하기

import { useState } from "react";
import styled from "styled-components";

// styled component에서 테마에 접근할 수 있음
const Container=styled.div`
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: ${(props)=>props.theme.bgColor};
`;
const H1 = styled.div`
  color:${(props)=>props.theme.textColor};
`;

function App() {
 
  return (
      <Container>
        <H1>Protected</H1>
      </Container>
  );
}

export default App;

 

- 결과

 

따라서 theme(테마)를 타입화 시켜서 타입스크립트에 의해 보호받을 수 있게 되었습니다. 타입스크립트가 theme이 무슨 속성을 가졌는지 알려주니까 실수를 하지 않을 수 있습니다. 타입스크립트는 컴파일 전 실수를 알려줍니다.