React Native Dark Theme using React Navigation Tutorial

Hello Guys, Welcome back with a new, very interesting tutorial which is in demand for almost every app. And that is Dark Theme. Today I am going to show you how we can implement Dark Theme in React native using React Navigation with manual as well as device based theme selection through React Native Dark Theme using React Navigation Tutorial.

The final result of React Native Dark Theme using React Navigation Tutorial:

react native dark theme react navigation

So Let’s begin…

Step – 1: Time to install the following required modules:

  • @react-native-async-storage/async-storage (version – 1.13.2 at the time of the creation of this post).
  • @react-navigation/native (version – 5.8.0 at the time of the creation of this post).
  • @react-navigation/drawer (version – 5.10.0 at the time of the creation of this post).
  • @react-navigation/stack (version – 5.10.0 at the time of the creation of this post).
  • react-native-gesture-handler (version – 1.8.0 at the time of the creation of this post).
  • react-native-reanimated (version – 1.13.1 at the time of the creation of this post).
  • react-native-safe-area-context (version – 3.1.8 at the time of the creation of this post).
  • react-native-screens (version – 2.11.0 at the time of the creation of this post).
  • react-native-vector-icons (version – 7.1.0 at the time of the creation of this post).
  • react-native-appearance (version – 0.3.4 at the time of the creation of this post).
  • react-native-responsive-screen (version – 1.4.1 at the time of the creation of this post).

Step – 2: Create a folder hierarchy /src/DarkTheme(under the root directory) and following 6 files under /src/DarkTheme directory.

  • index.js: Will contain the import and export statements.
  • navigation.js: This file contains the code for setting up the navigation related stuff. In our case StackNavigation, DrawerNavigator and NavigationContainer.
  • StackScreen.js: In this tutorial for the sake of simplicity, I am going to display same list of items for all four drawer screens. So, I have decided to create a single component for all screens. This file’s code is responsible to show the items listing.
  • CustomDrawer.js: This file’s code is responsible to create the Custom Drawer for our app.
  • ThemingContext.js: Simply having the code which is responsible for creating and exporting our Dark Theme context.
  • ThemingProvider.js: Will be responsible for creating the state, required functions to update the state variables in Context, getting/setting updated/selected theme value in the device storage using AsyncStorage API.

And following one file under /src directory.

  • services.js: Will contain common functions such as creating an array of items, Light & Dark Themes config stuff.

Step – 3: Write code for App.js file:

Step – 4: Implementation for /src/DarkTheme/index.js file:

Considerable Points:

  • On line no. 2, you can see import AppearanceProvider module from react-native-appearance. react-native-appearance is a module which enables our app to listen theme related changes occurred through device’s OS.

Step – 5: Implementation for /src/DarkTheme/ThemingContext.js file:

Step – 6: Implementation for /src/DarkTheme/ThemingProvider.js file:

Considerable Point(s):

  • Mainly this file is responsible for declaring and holding the state of our app’s theme and having the required functions which are responsible to update the app theme’s state and persisting the selected theme on the device storage using the AsyncStorage API.
  • fetchPersistedTheme in line no. 21 is responsible to check if there is already a persisted theme. If there is already a persisted theme then update our local theme state with the persisted theme and persist the state to the device storage and if there is no theme persisted already then make the first theme as the selected one and persist the selected one by executing updatePersistedTheme function in line no. 52.
  • And in line no. 81, updateTheme is a function that is responsible for updating our theme state variable.

Step – 7: Implementation for /src/DarkTheme/navigation.js file:

Considerable Point(s):

  • Mainly this file is responsible for setting and configure up the app navigation.
  • On line no. 13, you can see import useColorScheme from react-native-appearance module. useColorScheme is a hook which is subscribed to Color theme change updates by device.
  • On line no. 18, you can see we import CustomLightTheme, CustomDarkTheme and getSelectedTheme utilities from services.js files. CustomLightTheme and CustomDarkTheme are objects with some fixed standard keys used by the react-navigation regarding color scheming for its standards components. Such as, Stack headers, backgrounds, Tabbar background, text, icons etc.
  • On line no. 74, you can see that extracting the themes variable from Context and on line no. 75 fetch the selected theme. Then from line no. 78 to 89, check the selected theme id’s value and update the currentTheme variable according that and finally pass the currentTheme variable to theme prop of NavigationContainer.
  • If selectedTheme’s id is 1 then it means our app needs to follow the device theme’s configuration. If selectedTheme’s id is 2 then it means app should be in Light theme otherwise app should be in Dark theme.

Step – 8: Implementation for /src/DarkTheme/StackScreen.js file:

Considerable Point(s):

  • On line no. 17, you can see the import statement for useTheme hook. Basically, useTheme hook provided by @react-navigation/native and this hook subscribed Color theme change updates by react-navigation and we can extract all configurations related to selected theme. Such as, on line no. 63, we are extracting the colors objects from useTheme hook and we can access any property defined on colors object. Such as, on line no. 82, we are setting the background color of the view using backgroundColor: colors.background and as soon as the NavigationContainer’s theme props changes then useTheme hook executes and fetch the updated selected theme configurations. For ex. for light theme, we are setting the colors.background #F8F9FB’  and for dark theme, we are setting the colors.background #394143′. So, as soon as theme changes from light to dark we’ll receive ‘#394143’ as colors.background and from dark to light we’ll receive ‘#F8F9FB’ as colors.background through useTheme hook. The same concept applies for all other properties.

Step – 9: Implementation for /src/DarkTheme/CustomDrawer.js file:

Step – 10: Implementation for /src/services.js file:

That’s all guys. I hope you enjoyed this tutorial. Let me know how this tutorial helped you and share your thoughts through the comment section.

2 Comments

  1. Nice tutorial sir, But I need to ask you something can I change the dark theme into another color like brown or something other?

    • Thanks, James for your kind words. And yes you can change the dark color according to your app requirement. In the tutorial, You’ll find a file named services.js in which in line no. 48 and 49 you can provide your custom color and for more clarification, you can check the react-navigation documentation for configuring the colors for your theme.

Leave a Reply

Your email address will not be published. Required fields are marked *