🌞 Toggle theme 🌑 in React with MUI v5 and Redux 🚀
Tags: javascript, react, webdev, programming
Published: 2022-01-09 08:03:19

Dark and Light theme in any Web-App make it even more attractive. To build a theme enabled web-app in ReactJS with the help of Material-UI v5 and Redux follow this article.

---

![Theme Animation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lndxxbrzh8o0zwbk5dza.gif)

---

## Directory Structure

```
src
│   App.js
│   index.css
│   index.js
│
└───theme
│   │   theme.js
│
└───redux
│   │   store.js
│   │
│   └───theme
│       │   themeSlice.js
```

## Create a React Project

Using `npx` create a new react project.

```bash
$ npx create-react-app my-site
```

## Add dependencies

Add the following libraries

```bash
$ yarn add @reduxjs/toolkit react-redux @mui/material @emotion/react @emotion/styled
```

your `package.json` should look like this

```json
{
  "name": "my-site",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@emotion/react": "^11.7.1",
    "@emotion/styled": "^11.6.0",
    "@mui/material": "^5.2.7",
    "@reduxjs/toolkit": "^1.7.1",
    "@testing-library/jest-dom": "^5.16.1",
    "@testing-library/react": "^12.1.2",
    "@testing-library/user-event": "^13.5.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-redux": "^7.2.6",
    "react-scripts": "5.0.0",
    "web-vitals": "^2.1.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": ["react-app", "react-app/jest"]
  },
  "browserslist": {
    "production": [">0.2%", "not dead", "not op_mini all"],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
```

## Let's Write Code 🚀

> Start with Writing Store / Redux

To learn the basics of the new Redux using a simple `Counter App`, you may have a look at my recent article [New Redux 😱 is just 🔥](https://dev.to/rajeshj3/new-redux-is-just-3mle).

Create `themeSlice.js`

```js
import { createSlice } from "@reduxjs/toolkit";

export const themeSlice = createSlice({
  name: "theme",
  initialState: {
    darkTheme: false,
  },
  reducers: {
    toggleTheme: (state) => {
      state.darkTheme = !state.darkTheme;
    },
  },
});

export const { toggleTheme } = themeSlice.actions;

export default themeSlice.reducer;
```

In `initialState` the default value of `darkTheme` is `false`, i.e. by default the theme will be **light**.

> Register the `themeSlice` in store. So, your `store.js` should look like this.

```js
import { configureStore } from "@reduxjs/toolkit";
import theme from "./theme/themeSlice";

export default configureStore({
  reducer: {
    theme,
  },
});
```

> Don't forget to provide the store to the App in `index.js`

```js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import "./index.css";

// redux
import store from "./redux/store";
import { Provider } from "react-redux";

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);
```

> Let's write `theme/theme.js`

Define both light and dark themes in `theme.js`

```js
import { createTheme } from "@mui/material";

export const lightTheme = createTheme({
  palette: {
    mode: "light",
    background: {
      paper: "#f2f2f2",
    },
    text: {
      primary: "#11111",
    },
  },
});

export const darkTheme = createTheme({
  palette: {
    mode: "dark",
    background: {
      paper: "#222",
    },
    text: {
      primary: "#fff",
    },
  },
});
```

> Write `App.js`

Based on the Global state variable `darkTheme`, provide theme to `ThemeProvider HOC`.

```js
import { useSelector, useDispatch } from "react-redux";
import { ThemeProvider } from "@mui/material/styles";
import {
  Paper,
  FormGroup,
  FormControlLabel,
  Switch,
  Typography,
} from "@mui/material";

import { darkTheme, lightTheme } from "./theme/theme";
import { toggleTheme } from "./redux/theme/themeSlice";

export default function App() {
  // get theme from store
  const theme = useSelector((state) => state.theme);

  // initialize dispatch variable
  const dispatch = useDispatch();

  // ToggleSwitch component
  const ToggleSwitch = () => {
    return (
      <div
        style={{
          position: "absolute",
          top: "10px",
          right: "10px",
        }}
      >
        <FormGroup>
          <FormControlLabel
            control={
              <Switch
                checked={theme.darkTheme}
                onChange={() => dispatch(toggleTheme())}
              />
            }
            label="Toggle Theme"
          />
        </FormGroup>
      </div>
    );
  };

  return (
    <ThemeProvider theme={theme.darkTheme ? darkTheme : lightTheme}>
      <Paper
        style={{
          minHeight: "100vh",
          borderRadius: "0",
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        <ToggleSwitch />
        <Typography variant="h1">Hello</Typography>
      </Paper>
    </ThemeProvider>
  );
}
```

## Run the Development Server 🚀

```bash
$ yarn start
```

> Open [http://localhost:3000](http://localhost:3000/)

**Light Theme**

![Light Theme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqo1tqjwlpq9n3kwknxg.png)

**Dark Theme**

![Dark Theme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n1cmba2mtwt9ndhrl6yp.png)

---

Hurray! You just learned `🌞 Toggle theme 🌑 in React with MUI v5 and Redux 🚀`

---

I hope, you guys liked this quick tutorial. If so, then please don't forget to drop a Like ❤️

And also, help me reach **1k Subscribers** 🤩, on my [YouTube channel](https://www.youtube.com/channel/UCCO4jIqmQVFDmVeeaAO5obA).

Happy Coding! 😃💻