This library is useless. I am starting to contribute to theReact Native Reusables

Dark Mode

How to add dark mode support to your app using NativeWind and ThemeProvider.

  1. 1

    Add async-storage

    First, add the async-storage to your project using the following command:

    npx expo install @react-native-async-storage/async-storage

    First, add the async-storage to your project using the following command:

  2. 2

    Create ThemeProvider

    Then create a ThemeProvider component:

    import { PropsWithChildren, useEffect, useMemo, useState } from "react";
    import { useColorScheme } from "nativewind";
    import {
      DarkTheme,
      DefaultTheme,
      ThemeProvider as RNThemeProvider,
    } from "@react-navigation/native";
    import { useColorScheme as RNUseColorScheme } from "react-native";
    import AsyncStorage from "@react-native-async-storage/async-storage";
    
    DefaultTheme.colors.background = "white";
    DarkTheme.colors.background = "#09090B";
    
    export const ThemeProvider = ({ children }: PropsWithChildren) => {
      const [loaded, setLoaded] = useState(false);
      const { colorScheme, setColorScheme } = useColorScheme();
      const rnColorScheme = RNUseColorScheme();
    
      useEffect(() => {
        if (loaded) {
          (async () => {
            const theme = await AsyncStorage.getItem("theme");
    
            if (!theme) {
              const cs = rnColorScheme === "dark" ? "dark" : "light";
    
              await AsyncStorage.setItem("theme", cs);
              setColorScheme(cs);
              return;
            }
    
            if (colorScheme && theme !== colorScheme) {
              await AsyncStorage.setItem("theme", colorScheme);
              return;
            }
          })();
        }
      }, [colorScheme, loaded]);
    
      useEffect(() => {
        (async () => {
          const theme = await AsyncStorage.getItem("theme");
    
          if (theme) {
            setColorScheme(theme as "light" | "dark");
          }
    
          setLoaded(true);
        })();
      }, []);
    
      const isDarkMode = useMemo(
        () => (!loaded && rnColorScheme === "dark") || colorScheme === "dark",
        [loaded, rnColorScheme, colorScheme]
      );
    
      return (
        <RNThemeProvider value={isDarkMode ? DarkTheme : DefaultTheme}>
          {children}
        </RNThemeProvider>
      );
    };
    
  3. 3

    Wrap your app with ThemeProvider

    In your root layout file, wrap your app component with the ThemeProvider:

    import { ThemeProvider } from "@/providers/ThemeProvider"
    
    export default function RootLayout({ children }) {
      return (
        <ThemeProvider>
          {children}
        </ThemeProvider>
      )
    }
  4. 4

    Use the useColorScheme hook

    You can now use NativeWind's useColorScheme hook to manage the color scheme:

    import React, { useEffect } from 'react';
    import { useColorScheme } from "nativewind";
    import { Button } from "@/components/Button"
    import { Text } from "@/components/Text"
    
    function ThemeToggle() {
      const { colorScheme, setColorScheme } = useColorScheme();
    
      useEffect(() => {
        setColorScheme('dark');
      }, []);
    
      const toggleColorScheme = () => {
        setColorScheme(colorScheme === 'dark' ? 'light' : 'dark');
      };
    
      return (
        <Button onPress={toggleColorScheme}>
          <Text>Toggle theme (Current: {colorScheme})</Text>
        </Button>
      );
    }