¿Cómo agregar un tema dual a su aplicación React?

Los temas duales son muy comunes hoy en día en los sitios web, más comúnmente en las versiones clara y oscura, y cada vez más aplicaciones y sitios web incluyen esta función. Para las aplicaciones React, el marco Material UI proporciona funciones muy útiles que utilizan múltiples temas, y cambiar entre ellos es bastante fácil.

Crearemos una aplicación de reacción simple y cambiaremos entre temas oscuros y claros usando un componente Switch.

Creación de la aplicación React e instalación del módulo:

  • Paso 1: Cree una aplicación React usando el siguiente comando:

    npx create-react-app gfg
  • Paso 2: después de crear la carpeta de su proyecto, es decir, gfg , acceda a ella con el siguiente comando:

    cd gfg
  • Paso 3: después de crear la aplicación ReactJS, instale los módulos material-ui usando el siguiente comando:

    npm install @material-ui/core
  • Paso 4: Cree los siguientes dos archivos nuevos en la carpeta  src :

    • theme.js: en este archivo, definiremos nuestros objetos temáticos.
    • Component1.js: este es nuestro componente secundario de ejemplo.

Estructura del proyecto: Tendrá el siguiente aspecto.

El gancho useTheme:

Podemos importar varios temas desde nuestro archivo de tema y luego cambiar de tema en nuestro componente principal usando un componente Cambiar y su función de controlador. Pero surge un problema, ¿qué pasa con sus componentes secundarios y otros componentes anidados?

En una arquitectura de un solo tema, todos los componentes de una aplicación pueden importar el objeto del tema directamente desde el archivo theme.js y usarlo. Ahora, ¿cómo sabrían sobre el cambio de tema ya que hay temas duales? ¿Tendríamos que transmitir un accesorio que notifique a cada componente por separado que ‘ Oye, el tema activo ha cambiado ‘? Esa sería una forma bastante engorrosa e ineficiente de hacer esto.

Afortunadamente, Material-UI proporciona un gancho useTheme a través del cual podemos acceder a las variables del tema principal dentro de nuestros componentes React. Por lo tanto, no necesitamos importar el tema por separado y podemos usar cualquier objeto de tema que esté usando el componente principal. Por lo tanto, ahora, incluso si cambiamos los temas, se cambia en todo el árbol de componentes.

Sintaxis:

import { useTheme } from '@material-ui/core/styles';

function Component1() {
  const theme = useTheme();
}

Creando el objeto de tema oscuro:

Aunque Material UI viene con modos claros y oscuros incorporados, definiremos el objeto del tema oscuro por separado a medida que avanzamos, podemos tener la libertad de cambiar cada propiedad de manera distintiva en ambos temas, o incluso podría desear un tema gris en lugar de un tema oscuro 

const darkTheme = responsiveFontSizes(createMuiTheme({
  spacing: 4,
}));

Mantendremos las fuentes y tipografías del tema oscuro igual que el original. Cambiaremos el fondo a negro y los colores primarios/secundarios de la paleta a blanco como se muestra a continuación.

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} ;

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>
    );
}

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;

Paso para ejecutar la aplicación: ejecute la aplicación utilizando el siguiente comando desde el directorio raíz del proyecto:

npm start

Salida: Ahora abra su navegador y vaya a http://localhost:3000/ , verá la siguiente salida:

Publicación traducida automáticamente

Artículo escrito por abhijeetcatches33 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *