Who doesn't love dark mode?
I know I do! In this tutorial, we'll be taking a React application and adding in the new feature.
To keep with React / Redux best practices, the application should be a faithful representation of the current state. In order to implement the feature with this design pattern in mind, we'll be taking the following approach:
1) Adding a new component that renders a button
2) This new component will be responsible for dispatching an action
3) This action will update the application's state
4) Add a new reducer with a case to handle this request
5) Connect the header and footer components to Store
6) Have header and footer components render styling conditionally based off stores Dark Mode state
Start with the UI
I prefer to program in steps that seem logical, so let us start with making a button!
I opted to create this as a class component and connected this component to the Store so it could both dispatch an action to toggle the state of Dark Mode and connect to Store to receive the status of Dark Mode as a prop. This is helpful since the component is handling its own responsibilities, and also able to inform the user by changing the text of the button. Once we've created this component, don't forget to render the component within your own header file! It's as easy as importing the component to your header, and rendering the component wherever you'd like the button to display.
Wait a second, my button doesn't do anything yet!
Not to worry, next we'll create our new action. This is the action we're trying to dispatch on line 25 of the DarkMode.js component. Pop in to your actions folder, and create the following:
Excellent. Now let's head over to our reducer and create a new reducer. The only caveat here is if you are using multiple reducers. I am, so I've created a new reducer, pictured below, and added this reducer into my combineReducer function. I like this approach as 'darkMode' is now under its own key in reducer and not nested within other state for different parts of the application. It's easy to find at the root level, which is where I think someone else would try to find it. On line 11, we're able to set the default status of dark mode.
Check your dev tools!
At this point, we can examine state within our dev tools and see that the button component, when clicked should be properly dispatching the action and the state should be updating correctly. If you're working without dev tools that show state, the button should update its text between "Turn off Dark Mode" and "Turn on Dark Mode" when its clicked. This text is driven directly off the value stored in state.
Render color Schemes conditional on state's Dark Mode value
The final two steps are to alter your header and footer files to accept a prop linked to States Dark Mode value. This approach will vary depending on styling packages used and locations of styling within your application. For this project, I've used a Bootstrap template and by changing the class tags from 'dark' to 'light' and 'white' to 'black,' my color scheme inverts perfectly.
To leverage this built-in styling, I've connected my NavBar and Footer components to Store, and mappedStateToProps, handing in only the darkMode portion of state. Afterall, that's all these two components need to know about.
The final step is implementing a ternary operator, that evaluates if darkMode is set to True or False, and returns the dark color scheme if True, and the light color scheme if False. The styling is saved as a string to the variable and interpolated into the header.
The result
The header and footer color schemes invert themselves when the dark mode button is clicked! The button further provides information to the user to prompt them to turn on or off Dark Mode, providing a little more information than a standard button. This is a fun, easy-to-implement feature that gives the website a very different feel and may even encourage users to stay on your pages longer.
Top comments (0)