页面刷新后材质 UI 按钮失去样式

时间:2021-06-01 23:08:15

标签: javascript reactjs material-ui styling

我正在使用 useStyles 来设计我的登录页面。页面上的所有内容都有正确的样式,刷新后不会丢失,除了按钮。 按钮是页面中唯一在刷新后失去样式的东西。

登录.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>
  )
}

登录样式.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>
  );
}

刷新前:

https://i.imgur.com/Pi0j3rw.png

刷新后:

https://i.imgur.com/ManSuCC.png

1 个答案:

答案 0 :(得分:2)

JSS 按需创建样式的方式,Button 组件的核心样式覆盖了您使用 makeStyles 定义的样式,因为组件是在自定义样式之后导入的.如果您检查 Dev Tools 中的元素,您可以看到 .MuiButton-root 样式覆盖了生成的类 .makeStyles-button-2 下的样式——两个单类 CSS 选择器具有相同的特异性,因此出现的那个最后获胜。

要解决此问题,您只需对导入重新排序,以便在 useStyles 和其余 MUI 组件之后导入 Button

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