Nowadays, theres a ton of different kinds of amazing websites out there and all of them are great, but there’s something missing with those sites.
They don’t have a dual theme configuration. Theres always just one theme and its either a light mode or dark mode.
Adding these two small configurations makes the user experience much better.
So in this guide, I’m going to show you how to implement this using a popular Javascript framework called React, a global state management library called Redux, and a CSS in JS library called Emotion. Don’t worry, this all comes together really nicely.
1. Lets Get Started
Open up your preferred terminal. Now run these commands at once to initialize your react app.
$ npx create-react-app theme-switcher-react-demo$ cd theme-switcher-react-demo$ npm start
At this point, you should have a basic react website up and running! Now navigate to http://localhost:3000 to visit your app.
Now open up your favorite text editor, I’m using VSCode.
Make a folder in your src folder called components and redux. Inside the components folder make a folder called DarkLight, and within that folder create two javascript files, one called global.js and the other called theme.js
Since redux is very boilerplate heavy, I will give the starter code and I’ll link my Github repo with redux already set up.
2. Theming
Let’s make some theme colors for our light and dark themes.
Open up theme.js and slap some hex codes into there.
Now let’s move on to do our global css so we can put all of our other code between the global wrapper.
Navigate to your index.css file and add these lines of code inside.
These css classnames are just a set up for the wrapper you’re going to create in your global.js file.
3. React + Emotion
Here are some things we need to do
- Add the redux provider store to our render in index.js
- Retrieve the state inside the redux store which is going to be a boolean equating to true or false
- Whether it’s true or false, we need to be switching the className between two configurations, dark and light. ← This is all in the global js file
- And then export the global wrapper to wrap around all the other app components.
Now we have to install all the modules we’ll need for this. You can do this in all one go. Run this command
$ npm i --save react-redux redux @emotion/styled @emotion/react
In your index.js file lets add the Redux Store…
Perfect, our React App is now connected to the Redux Store. If you don’t have redux set up yet visit my Github Repo and clone the redux demo. You need to set up redux for this now.
Now let us enter our global.js file and retrieve the state we initialized it to in the redux store.
Looks cool.. And a little complicated 😂
So we imported React and something called useSelector from react-redux. What this does is basically fetches the state from the Redux Store.
So isDark will be either true or false depending on what the state is.
Now we use a ternary operator in classname to check if isDark is true, then we’ll use the name dark, otherwise we’ll use light.
Children is a prop so any other components we want to render inside, it’ll be easy.
4. Creating the Toggle Button
First we need to import everything we need regarding Emotion, React, and Redux.
Okay so I used Emotion styling to create a button component, and added props so I can differ which component is dark and which isn’t. It’s based on true and false so we’d like to match the global state as much as possible.
The new thing here is the useDispatch() hook. This is basically the action sent to the Redux Store to change the state or do whatever with it. So, useSelector() fetches the state, and useDispatch() does something with the state.
Now since we have to communicate the dispatch with the action, we imported it at the top of our file right here
import { dark } from "../redux";
So the last part is checking whether the state is dark and if it is then it switches to the dark configurations, otherwise it sticks with the light configurations.
You’re almost done!
5. Combine all your components!
Now all we have to do is render all of our components in our App.js file to make the changes.
Lets goo 🥳
Now save everything and navigate to http://localhost:3000 and check it out!
Try doing it yourself :)
— Ihsaan