0Pricing
React Native Academy · Pelajaran

Context Tema dengan Sakelar Mode Gelap

Bangun ThemeContext yang menyimpan skema warna saat ini, sediakan fungsi pengalih, lalu terapkan warna tema pada komponen di seluruh aplikasi.

Context Tema dengan Sakelar Mode Gelap adalah pelajaran React Native Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar React Native Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus React Native Academy mencakup 4 pelajaran total.

Bagian dari pelajaran ini belum diterjemahkan dan ditampilkan dalam bahasa Inggris.

Why a Theme Context?

A theme context centralizes color and typography values so that every component in the app reads from a single source of truth. When the user switches between light and dark mode, updating the context value triggers a re-render of all consuming components with the new colors — no prop drilling or manual updates required.

Defining Light and Dark Theme Objects

Start by defining two theme objects with the same keys. Using identical keys for both themes means every component can apply a color without knowing which mode is active — it just reads from the current theme object and both themes handle the rest.

export const lightTheme = {
  background: '#ffffff',
  text: '#1a1a2e',
  card: '#f5f5f5',
  primary: '#6200ee',
  border: '#e0e0e0',
};

export const darkTheme = {
  background: '#1a1a2e',
  text: '#e8e8f0',
  card: '#16213e',
  primary: '#bb86fc',
  border: '#333355',
};

Creating the ThemeContext

Create a ThemeContext that holds the current theme object and a toggle function. The default value mirrors the shape of what the Provider will supply, making it safe to destructure in consumers even if the Provider is accidentally missing in tests.

import { createContext, useContext, useState } from 'react';
import { lightTheme, darkTheme } from './themes';

export const ThemeContext = createContext({
  theme: lightTheme,
  isDark: false,
  toggleTheme: () => {},
});

Building the ThemeProvider

The ThemeProvider manages a boolean isDark state and derives the active theme object from it. The toggleTheme function flips the boolean. Memoize the context value with useMemo so that a new object reference is only created when isDark actually changes.

export function ThemeProvider({ children }) {
  const [isDark, setIsDark] = useState(false);

  const value = useMemo(() => ({
    theme: isDark ? darkTheme : lightTheme,
    isDark,
    toggleTheme: () => setIsDark((d) => !d),
  }), [isDark]);

  return (
    <ThemeContext.Provider value={value}>
      {children}
    </ThemeContext.Provider>
  );
}

A useTheme Custom Hook

Export a useTheme hook that wraps useContext(ThemeContext). Components call useTheme() for a clean, descriptive import instead of remembering to pass the context object. The hook also throws a helpful error if called outside a ThemeProvider.

export function useTheme() {
  const ctx = useContext(ThemeContext);
  if (!ctx) throw new Error('useTheme must be inside ThemeProvider');
  return ctx;
}

Applying Theme Colors to a Component

Any component that reads from useTheme will automatically display the correct colors for the current mode. Pass the theme colors into inline styles or StyleSheet styles. When the theme toggles, all consuming components re-render with the new values.

function Card({ title, body }) {
  const { theme } = useTheme();

  return (
    <View style={{
      backgroundColor: theme.card,
      borderColor: theme.border,
      borderWidth: 1,
      borderRadius: 8,
      padding: 16,
    }}>
      <Text style={{ color: theme.text, fontWeight: 'bold' }}>{title}</Text>
      <Text style={{ color: theme.text }}>{body}</Text>
    </View>
  );
}

A Toggle Switch in the Settings Screen

Add a dark mode switch to the settings screen. The Switch component's value is isDark from the theme context, and onValueChange calls toggleTheme. No local state needed — the toggle directly controls the global theme state.

function SettingsScreen() {
  const { isDark, toggleTheme, theme } = useTheme();

  return (
    <View style={{ backgroundColor: theme.background, flex: 1, padding: 24 }}>
      <Text style={{ color: theme.text }}>Dark Mode</Text>
      <Switch
        value={isDark}
        onValueChange={toggleTheme}
        trackColor={{ true: theme.primary }}
      />
    </View>
  );
}

Persisting the Theme Preference

Save the user's theme preference to AsyncStorage so it survives app restarts. In ThemeProvider, load the saved preference in a useEffect on mount and initialize state accordingly. Save the new value in toggleTheme whenever the user switches modes.

export function ThemeProvider({ children }) {
  const [isDark, setIsDark] = useState(false);

  useEffect(() => {
    AsyncStorage.getItem('theme').then((saved) => {
      if (saved === 'dark') setIsDark(true);
    });
  }, []);

  const toggleTheme = () => {
    const next = !isDark;
    setIsDark(next);
    AsyncStorage.setItem('theme', next ? 'dark' : 'light');
  };

  // ...
}

Respecting the System Theme

React Native's useColorScheme hook returns the device's current color scheme ('light' or 'dark'). You can use this as the default theme instead of always starting in light mode. If the user has not explicitly set a preference, respecting the system setting gives the best out-of-the-box experience.

import { useColorScheme } from 'react-native';

function ThemeProvider({ children }) {
  const systemScheme = useColorScheme();
  const [isDark, setIsDark] = useState(systemScheme === 'dark');
  // ...
}

Applying Theme to Navigation Header

The navigation header can also respond to theme changes. Pass a function to screenOptions on the navigator that reads from the theme context and returns header style options. When the theme changes, the navigator re-evaluates the options and updates the header colors accordingly.

function AppStack() {
  const { theme } = useTheme();

  return (
    <Stack.Navigator
      screenOptions={{
        headerStyle: { backgroundColor: theme.card },
        headerTintColor: theme.text,
      }}
    >
      <Stack.Screen name='Home' component={HomeScreen} />
    </Stack.Navigator>
  );
}

Preventing Flicker on Theme Load

When loading the saved theme from AsyncStorage on startup, there is a brief moment before the preference is restored. Prevent a flash of the wrong theme by showing a splash screen or delaying navigation until the theme is loaded. Use an isThemeReady state in the provider and render null until it is true.

const [isDark, setIsDark] = useState(false);
const [ready, setReady] = useState(false);

useEffect(() => {
  AsyncStorage.getItem('theme').then((saved) => {
    if (saved === 'dark') setIsDark(true);
    setReady(true);
  });
}, []);

if (!ready) return null; // prevent flash

Quick Check

Test your understanding of theme context and dark mode from this lesson.

Lesson Recap

In this lesson you learned: define separate light and dark theme objects with matching keys, provide both the active theme and a toggleTheme function through context, and persist the theme preference to AsyncStorage and restore it on app startup. Next up we explore avoiding context performance pitfalls.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Context Tema dengan Sakelar Mode Gelap” gratis?

Ya — teks lengkap “Context Tema dengan Sakelar Mode Gelap” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus React Native Academy, upgrade ke CoddyKit PRO. Kursus React Native Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Context Tema dengan Sakelar Mode Gelap”?

Bangun ThemeContext yang menyimpan skema warna saat ini, sediakan fungsi pengalih, lalu terapkan warna tema pada komponen di seluruh aplikasi. Kamu berlatih React Native Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai React Native Academy?

Tidak diperlukan pengalaman sebelumnya. React Native Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Context Tema dengan Sakelar Mode Gelap” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran React Native Academy ini?

Ya. Setiap pelajaran React Native Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Membuat dan Menyediakan Context
  2. Menggunakan Context dengan useContext
  3. Context Tema dengan Sakelar Mode Gelap
  4. Menghindari Masalah Performa Context
← Kembali ke React Native Academy