反应状态没有改变

React state isn't being changed

我对反应还很陌生,我正在尝试创建一个登录身份验证系统,到目前为止,它的工作方式与一件事不同。问题是当我使用应该将身份验证状态更改为 false 的注销功能时,它没有这样做。我刚刚读到状态更改是异步的,所以现在我很困惑执行的顺序是什么,因为我也有两个 useEffects。期望的结果是可以将身份验证设置为 false 并将用户名和密码设置为空字符串,这样当我刷新页面时我会保持注销状态。 (现在看来我已注销,因为登录页面已呈现,但当我刷新时它不会呈现,如果我输入 /home,它会工作,我的用户就是我登录的用户)。任何帮助或指点将不胜感激

我会把我遇到的代码放在开头,然后将整个文件放在底部供参考




import Header from './components/Header';
import { BrowserRouter as Router, Route, Routes, Navigate, useParams, useNavigate } from 'react-router-dom';
import './App.css';
import { useState, useEffect } from 'react';




function App() {


// these are the usernames and their corresponding passwords which //will be used for the authentication 

  var users = {
    "sebastian": "password",
    "henry": "hoover",
    "guest": "guest",
  }

  const [user, setUser] = useState({username: "", password: ""})


  const [isAuth, setIsAuth] = useState(false);

  
 
  const Logout = () => {
      setIsAuth(false);
      setUser({
        username: "",
        password: "", 
          })
      console.log(isAuth);

      console.log(user.username + "is the username state after logout and password: " + user.password);
      navigate('/Login');
  }

// log returns "henry is the username state after logout and //password: hoover


  
// two use effects which worked to keep me signed in, not signed out
  useEffect(() => {
    let u = localStorage.getItem("userUsername");
    let p = localStorage.getItem("userPassword");
    for (let key in users) {
      let value = users[key]
      if (u == key && p == value) {
        setIsAuth(true)
        setUser({
          username: u,
          password: p,
        }) 
        
      } else {
        setIsAuth(false);
        setUser({
          username: u,
          password: p,
        })
      }
    }
    
    
    
  }, [])

  useEffect(() => {

    for (let key in users) {
      let value = users[key]

      if(user.username == key) {
        if (user.password == value) {
          setIsAuth(true);
          localStorage.setItem("userUsername", user.username);
          localStorage.setItem("userPassword", user.password);
          console.log(user.username);
          console.log(user.password);
          console.log("oh no");
          
          
        } else {
          setIsAuth(false);
          localStorage.setItem("userUsername", "");
          localStorage.setItem("userPassword", "");
          
        }
      } 
      
      
    }
  },[user])

  
  
  return (

    <div className="App">
      
      
      <Routes>    
        {isAuth ? 
          <Route path="/Home" element={<><Header Logout={Logout}/><Home user={user}/></>}/> :
         
        
//inside the header component is where the sign out is called after //pressing a button 
          
      </Routes>        
    </div>
     
 
    
  );
}

export default App;

//THE HEADER COMPONENT RELEVANT CODE ONLY

import React, {useState} from 'react'
import { Link } from 'react-router-dom'


const Header = ({Logout}) => {
  const [active, setActive] = useState(false)


  const signout = () => {
    Logout();
  }

  const submitHandler = (e) => {
    e.preventDefault();
    signout();
}
  return (
    <div className='header'>
      
        <ul>
     
     
          <li>
            <Link to={'/'} onClick={submitHandler}>Sign Out</Link>
          </li>
        </ul>
      </nav>
    </div>
  )
}

export default Header



// THE WHOLE FILE

import Intro from './components/Intro';
import SignIn from './components/SignIn';
import Home from './components/Home';
import Header from './components/Header';
import { BrowserRouter as Router, Route, Routes, Navigate, useParams, useNavigate } from 'react-router-dom';
import './App.css';
import { useState, useEffect } from 'react';
import { unstable_renderSubtreeIntoContainer } from 'react-dom';
import { type } from '@testing-library/user-event/dist/type';
import 'bootstrap/dist/css/bootstrap.min.css';



function App() {

  const guestUser = {
    username: "guest",
    password: "guest",
  }

  var users = {
    "sebastian": "password",
    "henry": "hoover",
    "guest": "guest",
  }

  const [user, setUser] = useState({username: "", password: ""})
  const [error, setError] = useState("");
  const [test, setTest] =useState("");



  const navigate = useNavigate()
  const [isAuth, setIsAuth] = useState(false);

  const Login = details => {
    console.log(details);
    for (let key in users) {
      let value = users[key]

      if(details.username == key) {
        console.log("username matches, checking password");
        if (details.password == value) {
          console.log("password matches signed in");
          setIsAuth(true);
          setUser({username: key, password: value})
          navigate('/home');
        } else {
          console.log("details do not match");
          setError("Username and password do not match");
        }
      }
      
    }
  }

 
  const Logout = () => {
      setIsAuth(false);
      setUser({
        username: "",
        password: "", 
          })
      console.log(isAuth);

      console.log(user.username + "after logout and " + user.password);
      navigate('/Login');
  }

  

  useEffect(() => {
    let u = localStorage.getItem("userUsername");
    let p = localStorage.getItem("userPassword");
    for (let key in users) {
      let value = users[key]
      if (u == key && p == value) {
        setIsAuth(true)
        setUser({
          username: u,
          password: p,
        }) 
        
      } else {
        setIsAuth(false);
        setUser({
          username: u,
          password: p,
        })
      }
    }
    
    
    
  }, [])

  useEffect(() => {

    for (let key in users) {
      let value = users[key]

      if(user.username == key) {
        if (user.password == value) {
          setIsAuth(true);
          localStorage.setItem("userUsername", user.username);
          localStorage.setItem("userPassword", user.password);
          console.log(user.username);
          console.log(user.password);
          console.log("oh no");
          
          
        } else {
          setIsAuth(false);
          localStorage.setItem("userUsername", "");
          localStorage.setItem("userPassword", "");
          
        }
      } 
      
      
    }
  },[user])

  
  
  return (

    <div className="App">
      
      
      <Routes>    
        {isAuth ? 
          <Route path="/Home" element={<><Header Logout={Logout}/><Home user={user}/></>}/> :
          <Route path="/Login" element={<Intro Login={Login} error={error}/>}/>}
        
        
        <Route path="" element={isAuth ? <Navigate to ="/Home" /> :
          <Navigate to ="/Login"/>}/>
          
      </Routes>        
    </div>
     
 
    
  );
}

export default App;

//HEADER WHOLE FILE 

import React, {useState} from 'react'
import { MenuOutlined } from '@material-ui/icons'
import { Close } from '@material-ui/icons'
import { Link } from 'react-router-dom'


const Header = ({Logout}) => {
  const [active, setActive] = useState(false)

  const showMenu = () => {
    setActive(!active)
  }

  const signout = () => {
    Logout();
  }

  const submitHandler = (e) => {
    e.preventDefault();
    signout();
}
  return (
    <div className='header'>
      <div className='menu-icon'>
        <MenuOutlined className='menu' onClick={showMenu}/>
      </div>
      <nav className={active ? 'slider active' : 'slider'}>
        <ul>
          <div className='closed'>
            <Close className='close' onClick={showMenu}/>

          </div>
          <li>
            <Link to={'/'}>Create Microreactor</Link>
          </li>
          <li>
            <Link to={'/'}>View Microreactors</Link>
          </li>
          <li>
            <Link to={'/'} onClick={submitHandler}>Sign Out</Link>
          </li>
        </ul>
      </nav>
    </div>
  )
}

export default Header



已解决,我只需要 1 个使用效果就不会使事情复杂化,而不是更改状态来决定我是否通过身份验证,我更改了一个变量,如果该变量已更改,那么我将继续更改状态。我这样做是因为状态更改是异步的,如果您以后的代码依赖于同一功能中较早更改的状态,则不会在同一范围或功能中更新。

import Intro from './components/Intro';
import SignIn from './components/SignIn';
import Home from './components/Home';
import Header from './components/Header';
import { BrowserRouter as Router, Route, Routes, Navigate, useParams, useNavigate } from 'react-router-dom';
import './App.css';
import { useState, useEffect } from 'react';
import { unstable_renderSubtreeIntoContainer } from 'react-dom';
import { type } from '@testing-library/user-event/dist/type';
import 'bootstrap/dist/css/bootstrap.min.css';



function App() {

  const guestUser = {
    username: "guest",
    password: "guest",
  }

  const users = {
    "sebastian": "password",
    "henry": "hoover",
    "guest": "guest",
  }

  const [user, setUser] = useState({username: "", password: ""})
  const [error, setError] = useState("");
  const [test, setTest] =useState("");



  const navigate = useNavigate()
  const [isAuth, setIsAuth] = useState(false);

  const Login = details => {
    console.log(details);
    for (const key in users) {
      const value = users[key]

      if(details.username == key) {
        if (details.password == value) {
          setIsAuth(true);
          setUser({username: key, password: value});
          localStorage.setItem("userUsername", details.username);
          localStorage.setItem("userPassword", details.password);
          navigate('/home');
        } else {
          setError("Username and password do not match");
        }
      }
      
    }
  }

 
  const Logout = () => {
    setIsAuth(false);
    setUser({
      username: "",
      password: "", 
    })
    localStorage.setItem("userUsername", "");
    localStorage.setItem("userPassword", "");
    authenticated = false;
    
    navigate('/Login');
  }
  

  let authenticated = false

  useEffect(() => {
    const u = localStorage.getItem("userUsername");
    const p = localStorage.getItem("userPassword");
    for (const key in users) {
      const value = users[key]
      if (key == u && value == p) {
        user.username = u;
        user.password = p;
        authenticated = true;

      }
      
    }
    
    (authenticated && setIsAuth(true));

  }, []

  )

  
  return (

    <div className="App">
      
      
      <Routes>    
        {isAuth ? 
          <Route path="/Home" element={<><Header Logout={Logout}/><Home user={user}/></>}/> :
          <Route path="/Login" element={<Intro Login={Login} error={error}/>}/>}
        
        
        <Route path="" element={isAuth ? <Navigate to ="/Home" /> :
          <Navigate to ="/Login"/>}/>
          
      </Routes>        
    </div>
     
 
    
  );
}

export default App;