블로그 목록

NativeWind로 React Native 스타일링하기 — Tailwind 문법 그대로 앱에서

웹에서 Tailwind에 익숙해진 다음 React Native로 넘어오면 StyleSheet.create가 답답하게 느껴진다. 색 하나 바꾸려고 컴포넌트 아래까지 스크롤해서 스타일 객체를 찾고, 이름 짓고, style={styles.xxx}로 연결하고. 간단한 레이아웃 하나에도 손이 많이 간다.

NativeWind는 그 Tailwind 문법을 React Native에서 그대로 쓰게 해준다. className에 유틸리티 클래스를 적으면 빌드 타임에 네이티브 스타일로 변환된다. 웹이랑 앱을 같이 만드는 프로젝트라면 스타일 언어를 통일할 수 있어서 더 좋다.

설치

npx expo install nativewind tailwindcss react-native-reanimated react-native-safe-area-context

tailwind.config.js를 만들고 content 경로를 잡아준다.

// tailwind.config.js
module.exports = {
  content: ['./app/**/*.{js,jsx,ts,tsx}', './components/**/*.{js,jsx,ts,tsx}'],
  presets: [require('nativewind/preset')],
  theme: { extend: {} },
  plugins: [],
}

babel.config.js에 preset도 추가한다. 이걸 빠뜨리면 className이 무시되고 스타일이 아예 안 먹힌다.

// babel.config.js
module.exports = function (api) {
  api.cache(true)
  return {
    presets: [
      ['babel-preset-expo', { jsxImportSource: 'nativewind' }],
      'nativewind/babel',
    ],
  }
}

마지막으로 글로벌 CSS 파일을 만들어 앱 진입점에서 import 한다.

/* global.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

컴포넌트에서 쓰기

이제 style 대신 className을 쓰면 된다.

import { View, Text, Pressable } from 'react-native'

export default function Card({ title, onPress }: Props) {
  return (
    <View className="m-4 rounded-2xl bg-white p-5 shadow-md">
      <Text className="text-lg font-bold text-gray-900">{title}</Text>
      <Pressable
        className="mt-3 rounded-lg bg-blue-500 px-4 py-2 active:bg-blue-600"
        onPress={onPress}
      >
        <Text className="text-center font-semibold text-white">열기</Text>
      </Pressable>
    </View>
  )
}

웹 Tailwind와 거의 똑같다. active: 같은 상태 변형도 그대로 동작한다. 다만 hover:처럼 터치 기기에 의미 없는 변형은 빠져 있고, 모든 CSS 속성이 다 되는 건 아니다. flex, spacing, color, border, 폰트 정도는 대부분 커버된다.

다크 모드와 반응형

dark: 접두사로 다크 모드를, sm: 같은 브레이크포인트로 화면 크기 대응을 할 수 있다.

<View className="bg-white dark:bg-gray-900">
  <Text className="text-base text-gray-900 dark:text-gray-100 sm:text-lg">
    안녕하세요
  </Text>
</View>

다크 모드는 기본적으로 기기 설정을 따라간다. 직접 토글하고 싶으면 useColorScheme 훅으로 제어하면 된다.


StyleSheet가 나쁜 건 아니지만, 마크업 옆에 스타일이 바로 보이니까 컴포넌트를 읽고 고치는 속도가 확실히 빨라진다. 웹과 앱을 함께 굴리는 팀이라면 스타일 사고방식을 하나로 맞출 수 있다는 게 가장 큰 장점이다. 세팅에서 babel preset만 빼먹지 않으면 30분이면 붙는다.