DEV Community

Cover image for How To Theme Your App With React, Redux & SCSS
Ebuka Odini
Ebuka Odini

Posted on

How To Theme Your App With React, Redux & SCSS

An opinionated guide on how to theme your react application with SCSS and Redux.

Steps to follow

Create a new app with create-react-app

npx create-react-app myapp 
Enter fullscreen mode Exit fullscreen mode

Add structure to your app:

... src store theme theme.slice.js theme.actions.js rootReducer styles _themes.scss _themify.scss components layout layout.jsx layout.scss page home home.jsx about about.jsx App.js ... 
Enter fullscreen mode Exit fullscreen mode

Add these packages to the app

npm i @reduxjs/toolkit redux node-sass react-router-dom react-redux --save 
Enter fullscreen mode Exit fullscreen mode

Create the theme slice

// theme.slice.js import { createSlice } from '@reduxjs/toolkit' import { uiActions } from './ui.actions' export const uiSlice = createSlice({ name: 'ui', initialState: 'light-theme', reducers: uiActions }) export const { toggleTheme } = uiSlice.actions export default uiSlice.reducer 
Enter fullscreen mode Exit fullscreen mode

Create the theme action

// theme.action.js export const uiActions = { toggleTheme: state => { console.log(state); return state === 'dark-theme' ? 'light-theme' : 'dark-theme'; } }; 
Enter fullscreen mode Exit fullscreen mode

Create the reducer

// rootReducer.js import { configureStore } from '@reduxjs/toolkit' import uiReducer from './ui/ui.slice' export default configureStore({ reducer: { ui: uiReducer, } }) 
Enter fullscreen mode Exit fullscreen mode

Create your theme map

// themes.scss $themes: ( light: ( bg: #f5fcff, fg: #002433, ), dark: ( bg: #004966, fg: #f5fcff, ), ); 
Enter fullscreen mode Exit fullscreen mode

Create the themify @mixin

// themify.scss @import 'themes'; @mixin themify($property, $key, $themes: $themes) { // Iterate over the themes @each $theme, $colors in $themes { // Create a selector &.#{$theme}-theme, .#{$theme}-theme & { // Output the declaration #{$property}: map-get($colors, $key); } } } 
Enter fullscreen mode Exit fullscreen mode

Create the layout component

// layout.jsx import { useSelector, useDispatch } from "react-redux"; import { toggleTheme } from "../../store/ui/ui.slice"; import './layout.scss'; export default function Layout(props) { const theme = useSelector(state => state.ui); const dispatch = useDispatch(); return ( <> <header className={`${theme} container`}> <Header /> <button onClick={() => dispatch(toggleTheme())}>Toggle Theme</button> </header> <div className={`${theme} container`}> {props.children} </div> </> ) } 
Enter fullscreen mode Exit fullscreen mode

Apply styles to the layout

// layout.scss @import "../../assets/style/themify"; header { @include themify('background', 'body-bg'); } 
Enter fullscreen mode Exit fullscreen mode

Now create your pages

// home.jsx import { Layout } from "../../components/layout/layout"; export default function Home() { return ( <Layout> <section> Home Page </section> </Layout> ) } 
Enter fullscreen mode Exit fullscreen mode
// about.jsx import { Layout } from "../../components/layout/layout"; export default function About() { return ( <Layout> <section> About Page </section> </Layout> ) } 
Enter fullscreen mode Exit fullscreen mode

Create routes for the application

// App.js import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; import Home from './pages/home/home'; import About from './pages/about/about'; function App() { return ( <Router> <Switch> <Route exact path='/' component={Home} />  <Route exact path='/tasks' component={About} />  </Switch>  </Router>  ); } export default App; 
Enter fullscreen mode Exit fullscreen mode

The output:
Run the output on codepen.

Thanks.

Top comments (0)