Javascript 状态设置为useState不通过道具传递
我有一个功能组件,它使用onSubmit函数设置状态。问题是setState函数无法及时更新用户状态,以便在身份验证状态更改为true之前将其传递给用户属性。以下是我的组件的基本要点:Javascript 状态设置为useState不通过道具传递,javascript,reactjs,state,Javascript,Reactjs,State,我有一个功能组件,它使用onSubmit函数设置状态。问题是setState函数无法及时更新用户状态,以便在身份验证状态更改为true之前将其传递给用户属性。以下是我的组件的基本要点: import React, { useState } from 'react'; import axios from 'axios'; import { LoginForm } from './LoginForm'; import { LoggedIn } from './LoggedIn'; const {
import React, { useState } from 'react';
import axios from 'axios';
import { LoginForm } from './LoginForm';
import { LoggedIn } from './LoggedIn';
const { login } = require('../utils/login');
const { getUser } = require('../utils/getUser');
export const Splash = () => {
const [user, setUser] = useState(null);
const [authenticated, setAuthenticated] = useState(false);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const _handleEmail = (e) => {
setEmail(e.target.value);
};
const _handlePass = (e) => {
setPassword(e.target.value);
};
const _handleSubmit = async (e) => {
e.preventDefault();
const token = await login(email, password);
const fetchUser = await getUser(token);
setAuthenticated(true);
setUser(fetchUser);
console.log(fetchUser) <---- logs user fine
console.log(user) <----- logs empty object
};
const _handleLogout = async (e) => {
const logout = await
axios.get('http://localhost:5000/api/v1/auth/logout');
console.log(
`Logout status: ${logout.status}, Success: ${logout.data.success}`
);
setAuthenticated(false);
setUser({});
};
return (
<div>
{!authenticated ? (
<LoginForm
handleEmail={_handleEmail}
handlePass={_handlePass}
handleSubmit={_handleSubmit}
/>
) : (
<LoggedIn
user={user}
authenticated={authenticated}
logout={_handleLogout}
/>
)}
</div>
);
};
根据,useState与setState相同,触发新渲染
下一次渲染时,新值将出现在user
因为您使用的是异步方法,所以您脱离了循环,无法在下一行中看到新的状态值 请参阅:
在其中,异步函数等待2秒,然后设置状态。
您可以在控制台中看到,渲染是在设置状态之后触发的,渲染会看到新状态,但异步方法会打印旧状态 useState和setState是同步的,这意味着它们将直接触发渲染 对于异步工作,可以使用
useffect
根据,useState与setState相同,触发新渲染
下一次渲染时,新值将出现在user
因为您使用的是异步方法,所以您脱离了循环,无法在下一行中看到新的状态值 请参阅:
在其中,异步函数等待2秒,然后设置状态。
您可以在控制台中看到,渲染是在设置状态之后触发的,渲染会看到新状态,但异步方法会打印旧状态 useState和setState是同步的,这意味着它们将直接触发渲染
对于异步工作,您可以使用
useffect
为什么需要一个单独的标志来进行身份验证?您不能只检查是否设置了user
?使用LoggedIn
更新?您可以提供一个工作示例吗?为什么需要一个单独的标志进行身份验证?您不能检查是否设置了user
吗?使用LoggedIn更新您可以提供一个工作示例吗?
/// LoggedIn.js
export const LoggedIn = ({ logout, user, authenticated }) => {
LoggedIn.propTypes = {
logout: PropTypes.func.isRequired,
user: PropTypes.object.isRequired,
authenticated: PropTypes.bool.isRequired
};
const [loggedInUser, setUser] = useState({});
const [loggedInAuth, setAuthenticated] = useState(false);
useEffect(() => {
try {
if (user) {
setAuthenticated(true);
setUser(user);
}
} catch (err) {
console.log(err);
}
}, []);
return (
<div>
{!authenticated ? (
<Spinner animation='border' variant='primary' />
) : (
<LoggedinNav navUser={user} logoutButton={logout} />
)}
</div>
);
};
// LoggedInNav.js
export const LoggedinNav = ({ navUser, logoutButton }) => {
LoggedinNav.propTypes = {
navUser: PropTypes.object.isRequired,
logoutButton: PropTypes.func.isRequired
};
return (
<div>
<Navbar bg='light' variant='light'>
<Navbar.Brand href='#home'>
<img
src={logo}
width='120'
height='auto'
className='d-inline-block align-top ml-3'
alt='React Bootstrap logo'
/>
</Navbar.Brand>
<Nav className='mr-auto'>
<Nav.Link href='#feedback'>Submit Feedback</Nav.Link>
</Nav>
<Navbar.Collapse className='justify-content-end mr-4'>
<Navbar.Text>
Signed in as: {navUser.name.first} {navUser.name.last} - Role:{' '}
{navUser.role}
</Navbar.Text>
</Navbar.Collapse>
<Button onClick={logoutButton} variant='outline-primary mr-4'>
Logout
</Button>
</Navbar>
</div>
);
};