How to toggle dark theme in ReactJs?
Why Your Application Needs 2 Themes?
Nowadays, most of the applications we use have two type of themes: Dark Mode and Light Mode. Earlier, most of the applications we used had only light mode but dark mode helps to save battery on your devices as well. Some people prefer Light Mode, rest use Dark Mode, so it’s necessary to serve your all users right and make them feel comfortable using your application. Now, that we understood why we need dark mode, let’s jump into the tutorial!
The above gif shows the toggling of theme and this is how we are going to do!
Prerequisites
- A React App created with create-react-app
- Necessary Data added to your page.
Getting Started
My toggle button sits on the left side of the navigation bar and I usually prefer dividing different components in different files, so I have created DarkToggle.js file and is functional component with App.css file imported.
Designing The Web page
Our very first step is to design our web page, for both, dark and light theme. For this, we will be creating variables in CSS. Jump to your App.css file and in the html block of the code, define your variables like this:
html {--lightModeBackgroundColor: #f9fafc; // your colour--lightModeTitleColor: #25265e; // your colour}
Replace all your values of colours wherever used with these variables. After you’ve done this, you’ve set the light theme of your website. Next part is to configure the dark theme of your website. It is done in this way:
@media (prefers-color-scheme: dark) {html.dark {--lightModeBackgroundColor: #021f34;--lightModeTitleColor: #fff;}
Doing this configures the dark mode of your website. It won’t show up on the screen as of yet as the html tag gets rendered. Now, we have configured the design of the page, let’s jump to DarkToggle.js file.
Website Detecting Your PC Theme
Our next step is to show the user the theme he likes in the first instance. If he/she likes the light theme, we have to render the light mode of our page and if he/she likes the dark, we render the dark mode. To automatically detect this, in our DarkToggle.js file, first of all, we need to install react-responsive package using the command npm install react-responsive.
Next, we need to import useMediaQuery function from react-responsive like this:
import { useMediaQuery } from "react-responsive";
Now, we will create a const variable named systemPrefersDark and run the following code in it:
Next, we need to create useState hook named isDark like this:
const [isDark, setIsDark] = useState(systemPrefersDark);
To make this run, we need to add dark to our classlist. So first of all, we will create a global variable DARK_CLASS like this:
const DARK_CLASS = "dark";
Now, we will use the useEffect hook to add to classlist dark to toggle the themes. If the system prefers dark, we will add dark to our classlist, else we will remove, which will result in the running of the html and html.dark bloc of code in CSS to run. The useEffect will run whenever isDark value changes. The code goes as follows:
Toggle Button
Our last step is to create a toggle button and make it run. You can make your own custom toggle button but we will be using react-switch package.
To install it, simply go to the root of your project(where package.json file lies) and run the npm install react-switch command. Now, we have to import the switch to our file and it is done this way:
import Switch from "react-switch";
Now, we just need to return our Switch component that needs to be rendered on the screen. When the switch is checked, we need to show the sun icon and when its unchecked, we need to show the moon icon and whenever the switch is clicked, we need to toggle the theme. It becomes very easy for us because of the useEffect hook we used earlier which runs whenever the value of isDark changes. So, whenever Switch is clicked, we just need to change isDark value. It is done this way:
And we are done with toggling the theme of the website! If you have any doubts regarding this, comment below or message me on Instagram(link mentioned below)
Links
Code of Project Used To Demonstrate This: Portfolio Website
Link To The Website: RivaanRanawat
Instagram: OptimalCoding