React Native에서 Styled-Components와 theme 설정하기

냠냠·2024년 12월 9일

React Native Cli

목록 보기
2/2
post-thumbnail

📌 ESLint, Prettier까지 설정했다면, 이제 필수적인 라이브러리를 설치하고 관련된 설정을 완료해주어야합니다. 그 중에서 Styled-Components와 재사용성을 위한 theme 설정에 대해 알아봅시다!

여기서 잠깐! 많고 많은 CSS 라이브러리 중 왜 styled-components를 선택했을까요?

Styled-components를 선택한 이유

1. React Native와의 호환성

  • React Native에서는 DOM 요소 대신 View, Text와 같은 컴포넌트 사용 -> SCSS는 기본적으로 지원 X
  • styled-componentsReact Native의 기본 컴포넌트에 스타일을 적용할 수 있도록 최적화!

2. 동적 스타일링 지원

props를 사용해 컴포넌트에 동적으로 스타일을 전달할 수 있어 유연성 👍

3. CSS-in-JS의 장점

스타일과 컴포넌트를 한 파일에서 관리할 수 있어 가독성과 유지보수성 향상

이러한 이유로 MOA에서는 Styled-components를 사용하게 되었답니다. 그럼 본격적으로 사용 방법을 알아봅시다!


1. Styled-components 설치 및 파일 구조 셋팅

📌 기본적인 styled-components 라이브러리를 설치해주고,
타입스크립트 사용시 아래 타입 정의를 제공하는 패키지도 추가설치!

npm install styled-components

// 타입스크립트 사용시 
npm install --save-dev @types/styled-components @types/styled-components-react-native

📌 파일 구조 설정

src
│
├── assets       # 폰트 및 이미지 등 리소스
│   └── fonts
│   	└── 폰트 파일들
├── components   # 앱의 컴포넌트
│   └── Test.tsx
├── styles       # 스타일 관련 파일
│   ├── theme.ts
│   ├── styled.d.ts
│   ├── GlobalStyles.ts

2. ThemeProvider로 전역 테마 설정하기

📌 styled-componentsThemeProvider 사용
앱 전반에서 사용하는 색상, 폰트 크기, 간격 등을 한 곳에서 관리할 수 있는 기능 제공

  • 일관된 디자인 유지
  • 가독성과 유지보수성 향상
  • 재사용성

Step 1) 테마 정의 - theme.ts 파일

📌 앱 전체에서 사용할 색상, 폰트, 간격 등 전역적인 테마 설정

  • 값 자체 정의
  • props.theme.colors.maindarkorange 등으로 접근
  • ThemeProvider 적용: App.tsx에서 ThemeProvidertheme을 주입하여 앱 전체에서 사용할 수 있도록 설정
import 'styled-components';
export const theme = {
  colors: {
    maindarkorange: '#FF8521',
    mainlightorange: '#FFBF78',
    maindarkyellow: '#FFEEA9',
    mainlightyellow: '#FEFFD2',
    lightred: '#FAE5E3',
    lightyellow: '#FAEFD2',
    lightgreen: '#E4F2EB',
    lightblue: '#D9EAFA',
    ligthtpurple: '#F0E6F7',
    lightpink: '#FAE6EF',
    darkred: '#F26D68',
    darkyellow: '#FA9923',
    darkgreen: '#3CB580',
    darkblue: '#2A70BF',
    darkpurple: '#B666E8',
    darkpink: '#F569B1',
    lightgray: '#F8F8F8',
    mediumgray: '#F2F2F2',
    deepgray: '#838383',
    white: '#FFFFFF',
    black: '#000000',
  },
  fontSize: {
    small: '10px',
    regular: '16px',
    large: '18px',
    extralarge: '24px',
  },
  fontWeight: {
    light: '200',
    regular: '400',
    bold: '600',
    extrabold: '900',
  },
};

// 테마 타입 정의
export type ThemeType = typeof theme;

Step 2) DefaultTheme 확장 - styled.d.ts 파일

📌 styled.d.ts 파일을 생성해 DefaultTheme를 확장

import 'styled-components';
import {ThemeType} from './theme';

declare module 'styled-components' {
  export interface DefaultTheme extends ThemeType {}
}

Step 3) GlobalStyles.ts 파일 (참고)

// 초기에 만들어뒀다가, 사용하지 않음 
import {css} from 'styled-components/native';

export const GlobalStyles = css`
  font-family: 'SCDream5';
  font-size: ${({theme}) => theme.fontSize.extralarge};
  color: ${({theme}) => theme.colors.darkyellow};
`;

Step 4) App.tsx 에서 테마 주입

📌 ThemeProvider를 사용해 정의한 테마를 앱 전체에 전달

import React from 'react';
import {ThemeProvider} from 'styled-components/native';
import {theme} from './src/styles/theme';
import {SafeAreaView, Text, View} from 'react-native';
import styled from 'styled-components/native';
import Test from './src/components/Test';

const Container = styled.View`
  background-color: ${({theme}) => theme.colors.lightblue};
  padding: 10px;
`;

const App = () => {
  return (
    <ThemeProvider theme={theme}>
      <SafeAreaView>
        <Container>
          <View>
            <Test></Test>
          </View>
        </Container>
      </SafeAreaView>
    </ThemeProvider>
  );
};

export default App;

💡 주의) 타입스크립트에서 테마 관련 오류!

📌 타입스크립트를 사용하는 경우, ThemeProvidertheme 속성을 정의하지 않으면 오류가 발생할 수 있음.

// 오류 메시지 

Property 'theme' is missing in type '{ children: Element; }' but required in type 'Props'.ts(2741)
ThemeProvider.d.ts(31, 5): 'theme' is declared here.
(alias) function ThemeProvider(props: Props): React.JSX.Element | null
import ThemeProvider
Provide a theme to an entire react component tree via context

오류 원인

ThemeProvidertheme 속성의 타입을 기대하지만, 이 속성이 제대로 정의되지 않아서 발생

해결 방법

🔥 App.tsx에서 ThemeProvidertheme 주입할 때 속성 지정해주기

  • theme.ts에서 테마 객체에 타입을 정의 (ThemeType 생성).
  • styled.d.ts에서 DefaultTheme 확장.

3. 추가: 폰트 설정 및 안드로이드 연동

📌 React Native는 기본적으로 커스텀 폰트를 자동으로 인식하지 않는다!

  • react-native.config.js 파일을 통해 폰트 파일 경로를 설정하고,
  • npx react-native-asset 명령어를 실행해 폰트를 Android 및 iOS 프로젝트에 복사하기! - android폴더의 src에 폰트 파일들이 자동으로 저장됨

1) react-native.cofig.js 파일 생성

module.exports = {
  assets: ['./src/assets/fonts/'],
};

2) Android 프로젝트에 복사

  • 참고)
    npx react-native-asset 명령어는 react native 버전 0.69 밑일 때, npx react-native link 명령어는 0.69이상일 때 사용하는 것으로 알려져 있으나, moa는 최신 react native 버전임에도 link 명령어는 먹히지 않았음…
    🔥 관련 - 안드로이드와의 링크 이슈
npx react-native-asset // 채택! 
// 또는
npx react-native link

+) 🔥🔥🔥 추가

안드로이드와 폰트를 연결하기 위해 npx react-native-asset을 실행했지만, 안정적으로 연결되지 않는 문제가 발생.

  • 이 문제를 해결하기 위해, 폰트를 theme 객체에 추가하여 테마를 통해 폰트 스타일을 관리하는 방식으로 변경

4. 폰트 설치 후 재 빌드 필수!

1~3번까지 했는데 외 않되? 를 외치고 있다면, 재 빌드를 해보세요..

profile
프론트엔드 개발자

0개의 댓글