해당 포스트를 좀 더 보완한 useContext를 이용하여 다크모드 적용하는 것을 따로 포스팅했으니
참고하면 좋을 것 같다🧑🔧
React + Styled Components
일단 styled-components를 설치해주자.
yarn add styled-components
그리고 해야할 일은 프로젝트 내에 src 폴더에 global-styles.ts 파일과 theme.ts 파일을 만들어 주는 것이다.두 파일을 만들었으면 아래의 코드를 참고하여 입맛대로 설정을 해준다.
theme.ts
// theme.ts
export const lightTheme = {
bgColor: '#ffffff',
textColor: '#000000',
toggleBorder: '#FFF',
gradient: 'linear-gradient(#39598A, #79D7ED)',
}
export const darkTheme = {
bgColor: '#060606',
textColor: '#FFFFFF',
toggleBorder: '#6B8096',
gradient: 'linear-gradient(#091236, #1E215D)',
}
export const theme = {
lightTheme,
darkTheme,
}
export default theme;
global-styles.ts
// global-styles.ts
import { createGlobalStyle } from 'styled-components';
import reset from 'styled-reset';
export const GlobalStyle = createGlobalStyle`
${reset}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
align-items: center;
background: ${({theme} : {theme: any}) => theme.bgColor};
display: flex;
flex-direction: column;
justify-content: center;
height: 100vh;
margin: 0;
padding: 0;
transition: all 0.25s linear;
color: ${({theme} : {theme: any}) => theme.textColor};
}
button {
cursor: pointer;
border: none;
outline: none;
color: ${({theme} : {theme: any}) => theme.bgColor};
background-color: ${({theme} : {theme: any}) => theme.textColor};
}
`;
TypeScript 기준으로 해서 JavaScript 환경에서 코드를 작성하면 에러가 날 것이다. JavaScript 환경에서는 타입 설정을 해줄 필요가 없기 때문에 바로 사용한다.
// JavaScript
color: ${({ theme }) => theme.textColor};
background: ${({ theme }) => theme.bgColor};
그리고 App.tsx 파일로 가서 컴포넌트들에 GlobalStyle 적용을 해주고 ThemeProvider로 감싸줄 것이다. ThemeProvider Wrapper로 감싸주고 아래와 같이 theme를 넘겨주면 자식 컴포넌트에서 theme객체를 사용할 수 있게 된다.
App.tsx
// App.tsx
import React from 'react';
import { ThemeProvider } from 'styled-components';
import { lightTheme, darkTheme } from './theme';
import { GlobalStyle } from './global-styles';
function App() {
return (
<ThemeProvider theme={lightTheme}>
<>
<GlobalStyle />
<button>Dark Mode</button>
</>
</ThemeProvider>
);
}
export default App;
여기까지 하면 아래와 같이 못생긴 녀석이 화면에 나타난다. 다음은 버튼을 누르면 모드가 바뀌게 toggle 설정을 해줄 차례이다.
App.tsx
// App.tsx
import React, { useState } from "react";
import { ThemeProvider } from "styled-components";
import { lightTheme, darkTheme } from "./theme";
import { GlobalStyle } from "./global-styles";
function App() {
const [theme, setTheme] = useState("dark");
const isLight = theme === "light";
const toggleTheme = () => {
if (theme === "light") {
setTheme("dark");
} else {
setTheme("light");
}
};
return (
<ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}>
<>
<GlobalStyle />
<button onClick={toggleTheme}>Dark Mode</button>
</>
</ThemeProvider>
);
}
export default App;
이렇게 하면 Dark Mode라는 버튼을 누를 때 마다 light mode와 dark mode로 바뀌는 것을 볼 수 있다.
이제 버튼 스타일링을 해보자. button을 styled-components로 DarkModeToggleButton으로 선언한다.
App.tsx
// App.tsx
...
const DarkModeToggleButton = styled.button`
background: ${({ theme } : { theme: any }) => theme.gradient};
border: 2px solid ${({ theme } : { theme: any }) => theme.toggleBorder};
border-radius: 30px;
cursor: pointer;
display: flex;
font-size: 0.5rem;
justify-content: space-between;
margin: 0 auto;
overflow: hidden;
padding: 0.5rem;
position: relative;
width: 8rem;
height: 4rem;
svg {
height: auto;
width: 2.5rem;
transition: all 0.3s linear;
// sun
&:first-child {
transform: ${({ isLight } : { isLight: any }) => isLight ? 'translateY(0)' : 'translateY(100px)'};
}
// moon
&:nth-child(2) {
transform: ${({ isLight } : { isLight: any }) => isLight ? 'translateY(-100px)' : 'translateY(0)'};
}
}
`;
function App() {
...
JavaScript의 경우 아래와 같이 작성한다.
// JavaScript
background: ${({ theme }) => theme.gradient};
border: 2px solid ${({ theme }) => theme.toggleBorder};
그리고 App.tsx 파일에서 렌더링 하는 return 내에 다음과 같이 작성해준다.
// App.tsx
function App() {
...
return (
<ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}>
<>
<GlobalStyle />
<DarkModeToggleButton isLight={isLight}>
<img src={LightMode} alt='sun' onClick={toggleTheme}/>
<img src={DarkMode} alt='moon' onClick={toggleTheme}/>
</DarkModeToggleButton>
</>
</ThemeProvider>
);
}
'React' 카테고리의 다른 글
[React] TypeScript와 ESLint, Prettier 설정하기 (4) | 2020.10.11 |
---|---|
[React] scroll 이벤트 리스너 unmounted 처리 (0) | 2020.07.06 |
[React] 장소 검색 결과 카카오 지도에 나타내기 (6) | 2020.06.23 |
[React] 함수형 컴포넌트에서 카카오 지도 API 사용하기 (21) | 2020.06.13 |
[React] 맥북에서 AWS CLI 환경변수 설정하기 (0) | 2020.06.10 |