Theming React Applications with CSS Variables and React-Redux

Victor Adewusi
Bits and Pieces
Published in
5 min readMay 25, 2020

--

Hello World!

My name is Victor and I currently work as a React Developer and I must say, I love love React. It’s such a beautiful library. (Yes, React is a Library, Not a Framework, a Library).

Photo by Mika Baumeister on Unsplash

Recently I was tasked to come up with a Proof of Concept(POC) for a customized interface using React, SCSS and CSS modules. I decided to implement this with the classic Light and Dark Theme. I spent a huge amount of time doing research and could not find a solution to fit my needs until I found out about the all-consuming power of CSS Variables.

Note
There is no standard on theming React applications, however, it’s important you understand the limitations of whatever approach you choose to go along with. Skip to the end to find detailed resources on the various approaches to theming.

The Problem

The React application was built with SCSS+CSS modules (Thanks to Webpack) and even though it had modular style-sheets split up on a per component basis. the application still had a lot of SCSS code. So rewriting style-sheets was only considered as a last resort. I needed a solution that would fit right into my current architecture and allow customization at runtime.

The Solution — CSS Variables

According to Mozilla Developer Network(MDN),

Custom properties (sometimes referred to as CSS variables or cascading variables) are entities defined by CSS authors that contain specific values to be reused throughout a document.

The part about being able to reuse it throughout the document was super appealing and then further down the page on MDN, I found this beauty.

// JavaScript snippet to set CSS Variable
element.style.setProperty("--my-var", jsVar + 4);

This means

  1. I can setup reusable variables for my theme system.
  2. I can change those variables at runtime. In English, Switch my theme!

In essence I had everything I needed. Now to the fun part.

Demo: The Good Parts

To see a working demo, check here

Here’s what we’re looking to achieve

From L-R, Light Theme, Dark Theme

App Component

App Component

Here we import our Provider from react-redux, our global styles from the global CSS file, our Redux store, our theme applier component and the component we wish to apply the theme to (About Component).

Line 9: Creates a Redux Store.
Line 12: Passes the store to our Provider component from react-redux so it can easily be accessed by any component within our application.
Line 13: The Theme Applier Component which is responsible for the entire application’s themes.
Line 14: The About Component.

The About Component

The About Component

Line 8–17: Function to dispatch theme change action to Redux store based on button clicked by user.
Line 19–47: Visual Layout design of About Component.

Redux Configurations

Redux Configurations for Store, Actions and Reducers

Line 5–9: Action to change store to light theme
Line 11–15: Action to change store to dark theme
Line 18: Default state set to the light theme object
Line 21–30: Reducer Function to handle all actions dispatched
Line 33–36: Function to setup store, returns Redux store

CSS Variables and Styles

CSS Variables, theme object

Styles.css contains all of the default CSS style-sheets, while themes.js simply exports both our light mode and dark mode themes. It is important that our default style-sheet CSS variables matches up exactly with the default theme state (in this case, the light theme).

ApplyTheme Component

Apply Theme Component for applying themes across application

Line 6–19: Function to apply theme object to the document.
Line 13: Mirrors the JavaScript snippet as seen on MDN.
Line 21–23: A useEffect Hook to run when ApplyTheme mounts and when the theme object changes within the application (E.g when a user switches from light to dark mode or vice versa).
Line 29–32: Pass the theme state from the Redux store into the Apply Theme component using the mapStateToProps function.

Further Considerations

Now we have a way to add themes to our applications using CSS Variables and React-Redux. Here are a few things you might want to do for a standard production application.

  1. Split your Redux store configurations into separate folders including store, actions and reducers. A production application usually has more than one base object in its store. See combineReducers for more details.
  2. Upon refresh of our demo application, you may notice that it always goes back to the default light mode. This is because we currently have no system in place to persist the user’s preferred theme. You will need to store the user’s preference on a production database so their themes are consistent wherever and whenever they use your application.

Conclusion

We just witnessed the all consuming power of CSS Variables, although in a small scale, the principles applied here can very well be applied in any React application, production or otherwise.

I’m very much open to suggestions, comments and corrections. Feel free to reach out to me on Twitter

Thank you!

Further Readings

Tutorial to get you started on React-Redux
Three Ways To Theme React Components
Using CSS Custom Properties (Variables)
Motivation behind Redux

Publish and Reuse React Components with Bit

Publish reusable React components from any codebase to a single component hub. Use Bit to document, organize, and even keep track of component updates and usage.

Share components with your team to maximize code reuse, speed up delivery and build apps that scale.

Example: exploring React components published on Bit.dev

--

--