Hello Guys, Welcome back. Today I am going to show you how we can create our own very basic and simple custom themes in React native using AsyncStorage & Context API and through React Native Custom Theme using Context API Tutorial, I’ll show you how we can achieve this functionality.
The final result of React Native Custom Theme using Context API Tutorial:
So, let’s get started…
Step – 1: Install the following modules:
- @react-navigation/native (version – 5.7.6 at the time of the creation of this post).
@react-navigation/drawer (version – 5.9.3 at the time of the creation of this post).
- @react-navigation/stack (version – 5.9.3 at the time of the creation of this post).
@react-native-community/async-storage (version – 1.12.1 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).
Step – 2: Create a folder hierarchy /src/ThemingUsingContext(under the root directory) and create following 7 files under /src/ThemingUsingContext directory.
- CustomDrawer.js: Will contain code for our Custom Drawer.
- FeedScreen.js: Simply a Stack Navigator screen containing Navigation header, Header left button to open/close the Drawer, a simple counter in the middle of the screen, and a Floating Button to increase the counter.
- FloatingButton.js: Will contain the code for Floating Button.
- HomeScreen.js: Simply a Stack Navigator screen containing Navigation header, Header left button to open/close the Drawer, a simple counter in the middle of the screen, and a Floating Button to increase the counter.
- navigation.js: Will contain the navigation configuration related stuff.
- ThemingContext.js: Simply creating and exporting our custom 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 services.js file under /src directory.
- services.js: Will contain the details/data about our themes and other utility functions.
Fair enough? Okay, let’s start with some UI parts.
Step – 3: Implement code for HomeScreen.js & FeedScreen.js file(s):
- Starting from the return function of the HomeScreen/FeedScreen component(s). As you can see, these components simply render a StatusBar with dynamic barStyle prop to update the StatusBar style based on selected theme config, Text component responsible to show the counter(increased on the click on Floating Button) and a Floating Button.
- Get theme context using useContext hook and declare a state variable named count using useState hook.
- Configure header related config such as headerLeft, headerTitleAlign, headerTintColor, headerStyle and headerRight with dynamic values based on our selected theme. Although there is no purpose for the headerRight option. It’s just a hack to center align the header title.
Step – 4: Implement code for navigation.js file:
- On lines 16 & 17 create instances for Stack & Drawer navigators.
- Create Home and Feed stack navigators.
- Then create a Drawer navigator with custom content by providing drawerContent prop.
- And wrap our DrawerNavigator with NavigationContainer and ThemingProvider. Basically, all the child components would be able to access our custom theme context only when wrapped through our custom ThemingProvider. This is the concept of React Context API.
Step – 5: Implement code for CustomDrawer.js file which is responsible to customize our drawer content:
- As you can see in line no. 39, we are looping the routes array to render the drawer navigation items.
- Then Simply render our drawer items using the DrawerItem component provided by @react-navigation/drawer with custom styling based on the focused item and selected theme config.
- Then as you can notice from lines 68 to 89, we are looping our theme array(from context) to render all available theming thumbnails.
Step – 6: Implement code for ThemingContext.js file:
Step – 7: Implement code for ThemingProvider.js file:
- Mainly this file is responsible for declaring and holding the state of our app theme and containing the required functions which are responsible to update the app theme state and persisting the selected theme on the device storage using the AsyncStorage API.
- checkAlreadyPersistedTheme in line no. 18 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 if there is no persisted theme then make the first one as the selected theme by just updating the local state theme variable and then persist the state to the device storage by executing updatePersistedTheme function in line no. 61. Actually, the updatePersistedTheme function will execute every time when any changes happen in the theme state.
- And in line no. 81 updateTheme is a function that is responsible for updating our theme state variable.
Step – 8: Implement code for FloatingButton.js file:
Step – 9: Implement code for services.js file:
- As you can services.js file is containing 3 things. First one is defaultTheme, secondly themes array and lastly fetchSelectedTheme utility function which is responsible to fetch the selected theme.
Step – 10: Implement code for App.js file:
That’s it Guys, I hope you enjoyed this blog. Happy coding and be safe.