Ứng dụng mở ở light mode rồi không đổi màu khi người dùng chuyển hệ thống sang dark mode. Một nguyên nhân thường gặp là code đọc Appearance.getColorScheme tại cấp module, tính màu một lần rồi giữ nguyên object style đó cho các lần render sau.
Bài đối chiếu tài liệu React Native 0.88 ngày 01/11/2026. Mẫu dùng useColorScheme và component core. Chỉ logic chọn palette được chạy bằng Node; chưa build native hoặc thử thay đổi theme trên thiết bị, nên phần kiểm tra UI vẫn cần thực hiện trong dự án.
1. Giá trị hiện tại có thể thay đổi
useColorScheme theo dõi thay đổi từ Appearance và cung cấp giá trị cho render. Không cần tự đăng ký thêm listener chỉ để lặp lại chức năng cơ bản của hook trong ví dụ này.
Tài liệu đang tham chiếu có ba giá trị cần xét: light, dark và null khi native module không khả dụng. Mẫu chọn light làm fallback cho null. Đó là chính sách hiển thị của demo, không có nghĩa null được hệ điều hành định nghĩa là light.
2. Giữ palette tĩnh, chọn palette trong render
Các màu có thể được khai báo ở cấp module vì chúng là hằng số của thiết kế. Quyết định đang dùng bộ nào cần dựa trên giá trị hook ở lần render hiện tại.
import React from 'react';
import {StyleSheet, Text, View, useColorScheme} from 'react-native';
const palettes = {
light: {
background: '#ffffff',
surface: '#f1f5f9',
text: '#0f172a',
secondary: '#334155',
},
dark: {
background: '#0f172a',
surface: '#1e293b',
text: '#f8fafc',
secondary: '#cbd5e1',
},
};
export function paletteFor(scheme) {
return scheme === 'dark' ? palettes.dark : palettes.light;
}
export default function ThemeDemo() {
const scheme = useColorScheme();
const colors = paletteFor(scheme);
return (
<View style={[styles.screen, {backgroundColor: colors.background}]}>
<Text style={[styles.title, {color: colors.text}]}>Giao diện theo theme</Text>
<View style={[styles.card, {backgroundColor: colors.surface}]}>
<Text style={{color: colors.text}}>Scheme: {scheme ?? 'null'}</Text>
<Text style={{color: colors.secondary}}>
Đổi cài đặt giao diện rồi quay lại kiểm tra màn hình.
</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
screen: {flex: 1, padding: 24, justifyContent: 'center', gap: 16},
title: {fontSize: 24, fontWeight: '600'},
card: {padding: 16, borderRadius: 12, gap: 8},
});
Đặt component vào màn hình React Native đã có vùng chứa phù hợp. StyleSheet giữ phần bố cục không phụ thuộc theme; màu được thêm ở render. Không cần tạo lại toàn bộ hệ thống style chỉ để đổi một màu chữ.
3. Phép thử logic không phải phép thử native
Hàm paletteFor được trích nguyên từ snippet và kiểm tra trên Node.js 24.18.1 với light, dark và null. Kết quả chọn đúng object palette theo chính sách demo. Phép thử đó chưa chứng minh hook nhận được sự kiện hệ điều hành hoặc component render đúng trên Android/iOS.
Trong app thật, mở màn hình, đổi appearance ở cài đặt hệ thống rồi quay lại. Kiểm tra cả nền, chữ, màu phụ và các màn hình con. Nếu chỉ cập nhật background mà quên màu Text, giao diện có thể khó đọc dù hook đã cập nhật đúng.
Đọc scheme ở module rồi nhét màu vào StyleSheet một lần sẽ không tự tính lại khi hook ở component khác thay đổi. Hãy tìm nơi giá trị được chụp, thay vì thêm force update vào nhiều màn hình để bù cho snapshot cũ.
4. Phân biệt lựa chọn hệ thống và override của app
Appearance còn có khả năng override scheme ở cấp ứng dụng. Theo tài liệu hiện tại, setColorScheme với auto bỏ override để theo hệ thống; nó không thay đổi cài đặt appearance của hệ điều hành hoặc các app khác.
Mẫu không gọi API override và không có bộ chọn theme riêng. Nếu sản phẩm hỗ trợ ba lựa chọn sáng, tối, theo hệ thống, hãy xác định một nơi làm nguồn quyết định rồi kiểm tra cả ba chế độ. Đừng vừa giữ state riêng vừa override Appearance ở nhiều nơi mà không rõ thứ tự ưu tiên.
Lỗi thường gặp và giới hạn
Nếu máy luôn trả một scheme, kiểm tra cấu hình native của project và override đang tồn tại trước khi kết luận hook lỗi. Khi chụp screenshot trên iOS, tài liệu có lưu ý về thời điểm snapshot light/dark và cập nhật bất đồng bộ; cần phân biệt ảnh chụp với trạng thái UI đang tương tác.
Mẫu chưa cấu hình status bar, navigation bar, ảnh theo theme hoặc thư viện navigation. Nó cũng không tự chứng minh mọi cặp màu đạt tiêu chí tương phản của sản phẩm. Dùng checklist hiển thị và kiểm tra thiết bị để hoàn thiện các lớp đó sau khi logic chọn palette đã rõ ràng.




