How to add dark mode to your react native app 🌗

Ina HranovaIna Hranova 4 minutes 438 views

Share:

We can activate the dark mode 🌗 on Operation Systems, Applications, Docs, Websites by going to the respective app’s setting. I’m going to implement the Dark mode to one of the React Native applications. Most of the examples available on the Internet uses either styled-components. Yes, using with styled-components is very easy to add dark mode, but I want to keep it simple. That’s why I will show how we add Dark mode without styled-components. We will use React’s useContext and useState hooks to implement dark/light mode toggling. Context provides a way to pass data around your component tree without having to pass it through each parent to the child.

How to add dark theme to your react native app

Let’s get started

Let’s build the application which can toggle between light and dark mode. Create a react native app:

react-native init darkThemeApp

cd darkThemeApp

react-native run-ios

Open it in your favorite editor. I prefer to use the Visual Studio Code. Create a new folder theme and create new file  called  theme-context.js under theme directory.

//in file theme-context.js
const themes = { 
     dark: { 
         backgroundColor: 'black', 
         backgroundCard: '#25282c',
         color: 'white'
       }, 
      light: { 
        backgroundColor: 'white',
        backgroundCard: '#fff',
        color: 'black'
      } 
}

Let’s put the initial state in CreateContext.

//in file theme-context.js
import React from 'react';
const initialState = { 
   dark: false,
   theme: themes.light, 
   toggle: () => {}
 } 
const ThemeContext = React.createContext(initialState)

I have created a context named ThemeProvider. To be able to change the theme of all the components inside our app we must wrap all the components with ThemeProvider so that we can consume the value of context inside other components.

//in file theme-context.js

function ThemeProvider({ children }) {
const [dark, setDark] = React.useState(false) // Default theme is light

// To toggle between dark and light modes
const toggle = () => {
   setDark(!dark)
}

// Filter the styles based on the theme selected
const theme = dark ? themes.dark : themes.light

return (
    <ThemeContext.Provider value={{ theme, dark, toggle }}>
       {children}
    </ThemeContext.Provider>
    )
}
export { ThemeProvider, ThemeContext }

Open App.js and paste bellow code – wrapping our Card component in the ThemeProvider component that is rendering the Provider:

//in file App.js

import React from 'react';
import { ThemeProvider} from './theme/theme-context';

import Card from './components/Card';
const App = () => {
   return (
     <ThemeProvider>
       <Card />
     </ThemeProvider>
   );
};


export default App;

Let’s create a new component Card in directory components. Now let’s add the useContext to that Card component, allowing it to become a Consumer of the ThemeContext. The cool thing about this set up is that now all of those Consumers also have access to the toggle function we implemented in the ThemeProvider component. So we can create a toggle button like this:

//in componnents/Card.js

import React, { Component, useContext } from 'react';
import { View, Text, StyleSheet, Dimensions, Image, Button, Switch } from 'react-native';
import { ThemeContext } from '../theme/theme-context';

const Card = () => {
const { dark, theme, toggle } = useContext(ThemeContext);

return (
   <View style={[styles.container,{ backgroundColor: theme.backgroundColor }]} >
      <View style = {styles.containerSwitch}>
       <Switch
         trackColor={{ false: "#767577", true: "#ccc" }}
         thumbColor={dark ? "#fff" : "#f4f3f4"}
         onChange={toggle} value = {dark} />
     </View>
     <View style={[styles.containerCard, { backgroundColor: theme.backgroundCard }]}>
        <Image style={styles.img} 
              source={{ uri: 'https://images.unsplash.com/photo-1575908906110-6be79061f273?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1923&q=80' }} />
            <Text adjustsFontSizeToFit={true} style={[styles.text, { color: theme.color }]}>
          Nature, in the broadest sense, is the natural, physical, or material world or universe. 
         "Nature" can refer to the phenomena of the physical world, and also to life in general.
         The study of nature is a large, if not the only, part of science.
            </Text>
       </View>
    </View>
   );
}


export default Card;
const styles = StyleSheet.create({
   container: {
   flex: 1,
   justifyContent: 'center',
   alignItems: 'center'
},
containerSwitch:{
   marginBottom:50,
},
containerCard: {
   width: Dimensions.get('window').width - 50,
   borderRadius: 30,
   shadowColor: "#000",
   shadowOffset: {
     width: 0,
      height: 2,
   },
   shadowOpacity: 0.25,
   shadowRadius: 3.84,
   elevation: 5,
},
text: {
  fontSize: 20,
  padding: 20,
},
img: {
   width: Dimensions.get('window').width - 50,
   height: 240,
   borderTopLeftRadius: 30,
   borderTopRightRadius: 30,
}
});

You can also see the code for the whole project in this repo if you want to see it all put together. 

That’s all. This is what I wanted to share with you today, thanks for reading.

Peace out and ..

Welcome to dark side in react native