Implementar el Modo Oscuro y Claro en React Native

El modo oscuro/claro (dark mode y light mode) se han convertido en características esenciales en las aplicaciones móviles modernas. En React Native, es posible detectar automáticamente el esquema de color del sistema operativo y permitir a los usuarios cambiar el tema de forma manual.

  • Modo Claro (Light Mode): Es el esquema de colores tradicional, donde los fondos son claros y los textos son oscuros.
  • Modo Oscuro (Dark Mode): Es una opción visual con un fondo oscuro y texto claro, diseñada para ser más cómoda para los ojos en ambientes con poca luz y mejorar el rendimiento de la batería en dispositivos con pantallas OLED.

Implementación del Modo Oscuro y Claro en React Native

jsx
import React from 'react';
import { View, Text, StyleSheet, useColorScheme, Switch } from 'react-native';

const ThemeSwitcher = () => {
const systemScheme = useColorScheme();
const [isDarkMode, setIsDarkMode] = React.useState(systemScheme === 'dark');

const toggleTheme = () => setIsDarkMode(prev => !prev);

const backgroundColor = isDarkMode ? '#121212' : '#f2f2f2';
const textColor = isDarkMode ? '#ffffff' : '#000000';
const emoji = isDarkMode ? '🌙' : '🌞';

return (
      <View style={[styles.container, { backgroundColor }]}>
      <Text style={[styles.emoji, { color: textColor }]}>{emoji}</Text>
      <Text style={[styles.text, { color: textColor }]}>
          {isDarkMode ? 'Modo Oscuro Activado' : 'Modo Claro Activado'}
      </Text>
      <Switch
          value={isDarkMode}
          onValueChange={toggleTheme}
          thumbColor={isDarkMode ? '#f5dd4b' : '#f4f3f4'}
          trackColor={{ false: '#767577', true: '#81b0ff' }}
      />
      </View>
  );
};

const styles = StyleSheet.create({
  container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
  },
  emoji: {
      fontSize: 64,
      marginBottom: 10,
  },
  text: {
      fontSize: 20,
      marginBottom: 20,
      fontWeight: '600',
  },
});

export default ThemeSwitcher;


Ejemplo con el API Appearance.getColorScheme():

La API Appearance de React Native permite detectar el esquema de color del dispositivo y reaccionar a los cambios.

  • Appearance.getColorScheme(): Devuelve el esquema de color actual del dispositivo (claro u oscuro).
jsx
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, Appearance, Switch} from 'react-native';

const AppearanceExample = () => {
const [isDarkMode, setIsDarkMode] = useState(
  Appearance.getColorScheme() === 'dark'
);

useEffect(() => {
  const subscription = Appearance.addChangeListener(({ colorScheme }) => {
    setIsDarkMode(colorScheme === 'dark');
  });

  return () => subscription.remove(); // Limpieza al desmontar el componente
}, []);

const toggleTheme = () => setIsDarkMode(prev => !prev);

const backgroundColor = isDarkMode ? '#121212' : '#f2f2f2';
const textColor = isDarkMode ? '#ffffff' : '#000000';
const emoji = isDarkMode ? '🌙' : '🌞';

return (
    <View style={[styles.container, { backgroundColor }]}>
      <Text style={[styles.emoji, { color: textColor }]}>{emoji}</Text>
      <Text style={[styles.text, { color: textColor }]}>
        {isDarkMode ? 'Modo Oscuro Activado' : 'Modo Claro Activado'}
      </Text>
      <Switch
        value={isDarkMode}
        onValueChange={toggleTheme}
        thumbColor={isDarkMode ? '#f5dd4b' : '#f4f3f4'}
        trackColor={{ false: '#767577', true: '#81b0ff' }}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
  },
  emoji: {
      fontSize: 64,
      marginBottom: 10,
  },
  text: {
      fontSize: 20,
      marginBottom: 20,
      fontWeight: '600',
  },
});

export default AppearanceExample;