1

How To Theme Your App With React, Redux & SCSS

 2 years ago
source link: https://dev.to/ebukaodini/how-to-theme-your-app-with-react-redux-scss-55o1
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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 modeExit 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 modeExit fullscreen mode

Add these packages to the app

npm i @reduxjs/toolkit redux node-sass react-router-dom react-redux --save
Enter fullscreen modeExit 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 modeExit 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 modeExit 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 modeExit fullscreen mode

Create your theme map

// themes.scss
$themes: (
  light: (
    bg: #f5fcff,
    fg: #002433,
  ),
  dark: (
    bg: #004966,
    fg: #f5fcff,
  ),
);
Enter fullscreen modeExit 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 modeExit 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 modeExit fullscreen mode

Apply styles to the layout

// layout.scss
@import "../../assets/style/themify";

header {
  @include themify('background', 'body-bg');
}
Enter fullscreen modeExit 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 modeExit fullscreen mode
// about.jsx
import { Layout } from "../../components/layout/layout";

export default function About() {
  return (
    <Layout>
      <section>
        About Page
      </section>
    </Layout>
  )
}
Enter fullscreen modeExit 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 modeExit fullscreen mode

The output:
Run the output on codepen.

Thanks.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK