反应状态没有改变
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;
我对反应还很陌生,我正在尝试创建一个登录身份验证系统,到目前为止,它的工作方式与一件事不同。问题是当我使用应该将身份验证状态更改为 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;