Jackrin
Jackrin

Reputation: 83

Material UI Button loses Styling after page refresh

I'm using useStyles to style my login page. Everything on the page has the right style and it doesn't lose it after the refresh, apart from the button. The button is the only thing in the page that loses the styling after the refresh.

Login.js:

import { useEffect, useState, Fragment } from 'react';
import axios from 'axios'
import { BrowserRouter as Router, Switch, Route, MemoryRouter, Redirect, useHistory } from "react-router-dom";
import { useStyles } from './style/Login-styling'
import { Container, Grid, Paper, Avatar, TextField, Button, Typography, Link, Snackbar } from '@material-ui/core'
import MuiAlert from '@material-ui/lab/Alert';
import Slide from '@material-ui/core/Slide';
const bcrypt = require('bcryptjs');

function TransitionUp(props) {
  return <Slide {...props} direction="up" />;
}

function Alert(props) {
  return <MuiAlert elevation={6} variant="filled" {...props}  />;
}

export default function Login() {

  const [name, setName] = useState('')
  const [password, setPassword] = useState('')
  const [open, setOpen] = useState(false);
  const [alert, setAlert] = useState("Wrong credentials!");
  const history = useHistory();
  const classes = useStyles();

  async function csrf() {
    axios({
      method: 'GET',
      url: '/api/csrf',
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      credentials: "include",
      mode: 'cors'
    })
    .then(function(res) {
      localStorage.setItem('csrfToken', res.data.csrfToken)
    })
  }

  useEffect(() => {
    csrf();
  }, [])

  const passwordEnter = e => {
    if (e.code == "Enter") {
      login()
    }
  }; 
  const nameEnter = e => {
    if (e.code == "Enter") {
      document.getElementsByName('password')[0].focus()
    }
  }; 

  async function login() {
    axios({
      method: 'POST',
      url: '/api/login',
      headers: {
        'X-CSRF-Token': localStorage.getItem('csrfToken')
      },
      data: {
        name: name,
        password: password
      },
      credentials: "include",
      mode: 'cors'
    })
    .then(function(res) {
      if(res.data.result == "Login successful"){
        switch(res.data.job){
          case "doctor":
            history.replace("/dashboard1")
            break;
          case "pharmacist":
            history.replace("/dashboard2")
        }
      }
      else if (res.data.result == "Invalid credentials"){
        setAlert("Wrong credentials!")
        setOpen(true);
      }
    })
    .catch(function(err){
      if (err) {
        setAlert("Invalid CSRF Token!")
        setOpen(true);
      }
    })
  }

  const handleClose = (event, reason) => {
    if (reason === 'clickaway') {
      return;
    }

    setOpen(false);
  };

  return(
    <Fragment>
      <Container className={classes.container} component="main" maxWidth="xs">
        <div className={classes.paper}>
        <Typography variant="h3" className="title">Login</Typography>
          <div className={classes.form}>
            <TextField color="secondary" margin="normal" fullWidth variant="filled" label="Name" onKeyPress={(e) => nameEnter(e)} autoFocus={true} autoComplete="off" spellCheck="false" type="text" name="name" id="name" value={name} onChange={(e) => setName(e.target.value)}/> 
            <TextField color="secondary" margin="normal" fullWidth variant="filled" label="Password" onKeyPress={(e) => passwordEnter(e)} type="password" name="password" id="password" value={password} onChange={(e) => setPassword(e.target.value)}/>
          </div>
        <Button variant="contained" className={classes.button} onClick={login}>Login</Button>
        </div>
      </Container>
      <Snackbar open={open} autoHideDuration={6000} 
        onClose={handleClose}
      >
        <Alert onClose={handleClose} severity="error">
          {alert}
        </Alert>
      </Snackbar>
    </Fragment>
  )
}

Login-styling.js:

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

export const useStyles = makeStyles(() => ({
    container: {
        transform: 'translate(-50%)',
    },
    button: {
        background: 'rgba(255, 255, 255, 0.3)',
        color: 'rgba(255, 255, 255, 1)',
        fontSize: '110%',
        border: 0,
        borderRadius: 3,
        height: 48,
        width: '40%',
        padding: '0 30px',
        marginTop: '5%',
        '&:hover': {
            color: 'rgba(48, 48, 48, 1)',
         },
    },
    paper: {
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        marginTop: '60%',
    },
    form: {
        width: '80%'
    },
}));

App.js:

import { useState, useEffect } from 'react'
import { AnimatePresence, motion } from 'framer-motion'
import Login from './components/Login'
import Dashboard1 from './components/Dashboard2'
import Dashboard2 from './components/Dashboard1'
import Admin from './components/Admin'
import axios from 'axios'
import { BrowserRouter as Router, Switch, Route, MemoryRouter, Redirect, useHistory, Link, useLocation } from "react-router-dom";
import {Helmet} from "react-helmet";
import "./App.css";
import { MuiThemeProvider, createMuiTheme, responsiveFontSizes } from '@material-ui/core/styles';
import { colors } from '@material-ui/core';
import CssBaseline from '@material-ui/core/CssBaseline';

import 'fontsource-roboto';

export default function App(){
  const history = useHistory();
  let theme = createMuiTheme({
    palette: {
      type: 'dark',
      secondary: {
        main: colors.blue[200]
      }
    },
  });
  theme = responsiveFontSizes(theme)
  const location = useLocation()
  const pageTransition = {
    initial: {
      opacity: 0,
      y: "100vh",
    },
    in: {
      opacity: 1,
      y: 0,
      scale : 1
    },
    out: {
      opacity: 0,
      y: "-100vh",
      scale: 1,
    }
  }

  const transitionOptions = {
    type: "spring",
    ease: "anticipate",
    duration: 0.6,
    delay: 0.5
  }
  
  return (
    <MuiThemeProvider theme={theme} style={{position: 'relative'}}>
      <CssBaseline />
        <AnimatePresence>
          <Switch location={location} key={location.pathname}>
            <Route exact path="/">
              <motion.div 
                initial="false" 
                animate="in" 
                exit="out" 
                variants={pageTransition} 
                transition={transitionOptions}
                style={{position: 'absolute', left: '50%'}}
              >
                <Login />
              </motion.div>
            </Route>
            <Route path="/dashboard1">
              <motion.div 
                initial="initial" 
                animate="in" 
                exit="out" 
                variants={pageTransition} 
                transition={transitionOptions}
                style={{position: 'absolute'}}
              >
                <Dashboard1 />
              </motion.div>
            </Route>
            <Route path="/dashboard2">
            <motion.div 
                initial="initial" 
                animate="in" 
                exit="out" 
                variants={pageTransition} 
                transition={transitionOptions}
                style={{position: 'absolute'}}
              >
                <Dashboard2 />
              </motion.div>
            </Route>
            <Route path="/admin">
              <motion.div initial="initial" animate="in" exit="out" variants={pageTransition}>
                <Admin />
              </motion.div>
            </Route>
          </Switch>
        </AnimatePresence>
    </MuiThemeProvider>
  );
}

Before refresh:

https://i.sstatic.net/EIQMA.png

After refresh:

https://i.sstatic.net/ftBXA.png

Upvotes: 6

Views: 5224

Answers (1)

andrewpomeroy
andrewpomeroy

Reputation: 141

The way JSS creates styles on-demand, the core styles for the Button component are overriding the styles you've defined with makeStyles simply because the components are imported after the custom styles. If you inspect the element in Dev Tools, you can see that the .MuiButton-root styles are overriding those under the generated class .makeStyles-button-2 -- two single-class CSS selectors have the same specificity, so the one that comes last ends up winning.

To fix this, you'll just want to reorder your imports, so that useStyles is imported after the Button and the rest of your MUI components.

https://codesandbox.io/s/laughing-lamport-0i1zt?file=/src/components/Login.js

Upvotes: 8

Related Questions