Open In App

How to add dual theme to your React App ?

Last Updated : 04 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Dual Themes are very common nowadays in websites most commonly the light and dark versions and more and more apps and websites are including this feature. For React apps, the Material UI framework provides very useful functions using multiple themes, and switching between them is quite easy. In this article we will create a simple react app and switch between Dark and Light themes using a Switch component.

Prerequisites

Steps to create React Application And Installing Module:

Step 1: Create a React application using the following command:

npx create-react-app gfg

Step 2: After creating your project folder i.e. gfg, move to it using the following command:

cd gfg

Step 3: After creating the ReactJS application, Install the material-ui modules using the following command:

npm install @material-ui/core

Project Structure:

Example: Demonstrating dual theme in react app.

Javascript




// theme.js
 
import { createMuiTheme, responsiveFontSizes } from "@material-ui/core/styles";
 
const lightTheme = responsiveFontSizes(
    createMuiTheme({
        spacing: 4,
        typography: {
            fontFamily: ["Roboto", "Raleway", "Open Sans"].join(","),
            h1: {
                fontSize: "5rem",
                fontFamily: "Raleway",
            },
            h3: {
                fontSize: "2.5rem",
                fontFamily: "Open Sans",
            },
        },
        palette: {
            background: {
                default: "#009900", //green
            },
            primary: {
                main: "#009900", //green
            },
            secondary: {
                main: "#000000", //black
                icons: "#009900", //white
            },
            text: {
                primary: "#000000", //black
                secondary: "#FFFFFF", //white
            },
        },
    })
);
 
const darkTheme = responsiveFontSizes(
    createMuiTheme({
        spacing: 4,
        typography: {
            fontFamily: ["Roboto", "Raleway", "Open Sans"].join(","),
            h1: {
                fontSize: "5rem",
                fontFamily: "Raleway",
            },
            h3: {
                fontSize: "2.5rem",
                fontFamily: "Open Sans",
            },
        },
        palette: {
            background: {
                default: "#000000", //black
            },
            primary: {
                main: "#FFFFFF", //white
            },
            secondary: {
                main: "#FFFFFF", //white
                icons: "#FFFFFF", //white
            },
            text: {
                primary: "#FFFFFF", //white
                secondary: "#FFFFFF", //white
            },
        },
    })
);
 
export default lightTheme;
export { darkTheme };


Javascript




// App.js
 
import React, { Component } from "react";
import "./App.css";
import CssBaseline from "@material-ui/core/CssBaseline";
import { ThemeProvider } from "@material-ui/styles";
import { createMuiTheme } from "@material-ui/core/styles";
import Container from "@material-ui/core/Container";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";
import { AppBar, Toolbar } from "@material-ui/core";
import Switch from "@material-ui/core/Switch";
import lightTheme, { darkTheme } from "./theme";
import Grid from "@material-ui/core/Grid";
import Component1 from "./Component1";
 
function App() {
    // The 'checked' state is for the status of Switch component
    const [checked, setChecked] = React.useState(false);
    // The 'newtheme' state tells if the new theme (i.e, dark theme)
    // is to be applied or not.
    const [newtheme, setTheme] = React.useState(false);
    function changeTheme() {
        setTheme(!newtheme);
        setChecked(!checked);
    }
    // Conditional - if newtheme is set to true
    // then set appliedTheme to dark
    const appliedTheme = createMuiTheme(newtheme ? darkTheme : lightTheme);
    return (
        <React.Fragment>
            <ThemeProvider theme={appliedTheme}>
                <CssBaseline />
                <AppBar position="static" color="transparent" elevation={0}>
                    <Toolbar>
                        {/* Switch position whenever
                changed triggers the changeTheme() */}
                        <Switch
                            checked={checked}
                            onChange={() => {
                                changeTheme();
                            }}
                            style={{
                                color: appliedTheme.palette.secondary.icons,
                            }}
                        />
                    </Toolbar>
                </AppBar>
                <Container maxWidth="sm">
                    <Typography
                        component="h1"
                        variant="h1"
                        align="center"
                        color="textPrimary"
                        gutterBottom
                    >
                        Geeks for Geeks
                    </Typography>
                    <br />
                    <Component1></Component1>
                    <br />
                    <Grid
                        container
                        direction="row"
                        justify="center"
                        spacing={4}
                    >
                        <Grid item>
                            <Button variant="contained" color="secondary">
                                Button 1
                            </Button>
                        </Grid>
                        <Grid item>
                            <Button variant="outlined" color="secondary">
                                Button 2
                            </Button>
                        </Grid>
                    </Grid>
                    <br />
                </Container>
            </ThemeProvider>
        </React.Fragment>
    );
}
 
export default App;


Javascript




// Component1.js
 
import React, { Component } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { useTheme } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
 
const useStyles = makeStyles((theme) => ({
    root: {
        flexGrow: 1,
    },
}));
 
export default function Component1() {
    const theme = useTheme();
    const classes = useStyles(theme);
    return (
        <div className={classes.root}>
            <Typography
                variant="h3"
                align="center"
                color="textPrimary"
                paragraph
            >
                This is a Child Component text.
            </Typography>
        </div>
    );
}


Step to Run Application: Run the application using the following command from the root directory of the project:

npm start

Output: Now open your browser and go to http://localhost:3000/, you will see the following output:



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads