framework/ReactNative
갓난애기도 배울 수 있는 React Native 가이드 ⏺️ 보너스편2 – 다크모드 지원하기 (useColorScheme 완전 정복)
octo54
2025. 4. 24. 11:36
반응형
갓난애기도 배울 수 있는 React Native 가이드 ⏺️ 보너스편2 – 다크모드 지원하기 (useColorScheme 완전 정복)
지금까지 만든 앱은 흰 배경에 검은 텍스트만 보여주는 라이트 모드 전용이었습니다.
하지만 요즘은 다크모드가 기본입니다.
React Native는 이를 위한 훌륭한 API, useColorScheme() 를 제공합니다.
이번 글에서는 다크모드를 자동으로 감지하고, 테마를 적용하는 방법을 알려드립니다. 🌙✨
✅ 1. useColorScheme이란?
import { useColorScheme } from 'react-native';
- 현재 시스템 테마(Light/Dark)를 감지하는 Hook
- 반환값은 'light' 또는 'dark'
- 매 렌더링마다 자동 업데이트됨
✅ 2. 기본 사용 예제
import { useColorScheme, Text, View } from 'react-native';
const MyComponent = () => {
const scheme = useColorScheme(); // 'light' 또는 'dark'
return (
<View style={{ backgroundColor: scheme === 'dark' ? '#000' : '#fff', flex: 1 }}>
<Text style={{ color: scheme === 'dark' ? '#fff' : '#000' }}>
현재 모드: {scheme}
</Text>
</View>
);
};
✅ 3. 테마 기반 스타일 객체 만들기
반응형
const getStyles = (scheme) => ({
container: {
flex: 1,
backgroundColor: scheme === 'dark' ? '#121212' : '#ffffff',
padding: 20,
},
text: {
color: scheme === 'dark' ? '#ffffff' : '#000000',
fontSize: 18,
},
});
✅ 4. 기존 HomeScreen에 다크모드 적용하기
🔧 수정 포인트
- useColorScheme() 도입
- 스타일을 조건부로 렌더링
📄 HomeScreen.js (일부 수정)
import React, { useEffect, useState } from 'react';
import {
View, Text, TextInput, FlatList, Button, TouchableOpacity,
Pressable, StyleSheet, useColorScheme
} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
export default function HomeScreen({ navigation }) {
const scheme = useColorScheme(); // light or dark
const isDark = scheme === 'dark';
const [text, setText] = useState('');
const [todos, setTodos] = useState([]);
// ... 생략: loadTodos, saveTodos, addTodo, toggleDone, deleteTodo
const styles = getStyles(isDark);
return (
<View style={styles.container}>
<TextInput
placeholder="할 일을 입력하세요"
placeholderTextColor={isDark ? '#aaa' : '#666'}
value={text}
onChangeText={setText}
style={styles.input}
/>
<Button title="추가하기" onPress={addTodo} />
<FlatList
data={todos}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<Pressable
style={styles.todoItem}
onPress={() => navigation.navigate('Detail', { todo: item })}
>
<Text style={[styles.todoText, item.done && styles.done]}>
{item.done ? '✅' : '⬜️'} {item.title}
</Text>
<View style={styles.actions}>
<Button title={item.done ? '취소' : '완료'} onPress={() => toggleDone(item.id)} />
<Button title="삭제" color="red" onPress={() => deleteTodo(item.id)} />
</View>
</Pressable>
)}
ListEmptyComponent={<Text style={styles.emptyText}>할 일이 없습니다.</Text>}
style={{ marginTop: 20 }}
/>
</View>
);
}
// 🎨 다크모드 대응 스타일 함수
const getStyles = (isDark) =>
StyleSheet.create({
container: {
flex: 1,
padding: 20,
paddingTop: 60,
backgroundColor: isDark ? '#121212' : '#ffffff',
},
input: {
borderWidth: 1,
borderColor: isDark ? '#444' : '#aaa',
backgroundColor: isDark ? '#1e1e1e' : '#f9f9f9',
color: isDark ? '#fff' : '#000',
padding: 10,
marginBottom: 10,
borderRadius: 6,
},
todoItem: {
padding: 12,
borderBottomWidth: 1,
borderColor: isDark ? '#444' : '#eee',
},
todoText: {
fontSize: 18,
color: isDark ? '#fff' : '#000',
},
done: {
textDecorationLine: 'line-through',
color: isDark ? '#999' : '#999',
},
actions: {
flexDirection: 'row',
gap: 10,
marginTop: 8,
},
emptyText: {
marginTop: 20,
color: isDark ? '#888' : '#333',
},
});
✅ 5. 다크모드 UX 최적화 팁
항목 처리 방법
placeholderTextColor | 따로 지정 필요 |
borderColor, backgroundColor | 테마 조건부 처리 |
글로벌 테마 관리 | Context API 또는 styled-components 권장 (고급편) |
✅ 6. 이번 글에서 배운 내용
- 시스템 다크모드 감지 useColorScheme()
- 조건부 스타일 처리 방식
- 기존 컴포넌트에 다크모드 적용
- 사용자 친화적 UI 개선 기법
📘 다음 확장 예고
Firebase 연동으로 클라우드 저장소와 로그인 기능 구현하기
또는
앱 상태를 Context API + AsyncStorage로 전역관리하는 구조 만들기
React Native 다크모드,React Native useColorScheme,React Native 스타일 조건부 처리,React Native 테마 적용,React Native 다크모드 예제,React Native 색상 동적 변경,React Native 라이트모드,React Native UI 개선,React Native 스타일 자동 적용,React Native 테마 기반 앱