React 上下文在第一次登录时返回 undefined,但在页面刷新时有效 [英] React context returns undefined on first login, but works on page refresh
问题描述
我正在学习 React Context &在 HOC 上使用它,以便我可以在我的应用程序中查看用户是否已登录.登录后,我从上下文中获取用户名 &在标题中显示它.以前一切正常,但现在突然之间,用户首次登录时不显示名称,但刷新页面后立即正常显示.
I'm learning React Context & using it on a HOC so that i can see if a user is logged in or not throughout my app. Once logged in, i'm getting the users name from the context & displaying it in the header. It all worked fined before but all of a sudden now, the name is not displaying when the users first logs in, but displays normally as soon as you refresh the page.
这是我的 HOC
import React, { createContext, useState, useEffect } from "react";
// Custom Components
import {getAuthenticatedUser} from '../../apis/usersApi'
// App global Context
export const ContactManagerContext = createContext();
// Global context provider, provides context to all child components
export const Provider = (props) => {
// initial user authentication state
const [isAuthenticated, setAuthentication] = useState();
useEffect(() => {
onLoad();
},[]);
// gets & sets user authentication state on component render
const onLoad = async () => {
const user = await getAuthenticatedUser();
if(user) isAuthState(user);
};
const isAuthState = (user) => {
setAuthentication(() => user)
}
// updates user state when logged in successfully
const handleLogin = (user) => {
console.log(user)
isAuthState(user);
};
// updates userAuth state when logged out successfully
const handleLogout = () => {
isAuthState(null);
};
return (
<ContactManagerContext.Provider
value={{
isAuthenticated,
actions: {
handleLogin,
handleLogout
},
}}
>
{props.children}
</ContactManagerContext.Provider>
);
};
// Global context consumer
export const Consumer = ContactManagerContext.Consumer;
// wraps a component and provides context to it
export default function withContext(Component){
return function contextComponent(props){
return (
<ContactManagerContext.Consumer>
{context => <Component {...props} context={context} />}
</ContactManagerContext.Consumer>
)
}
}
这里的组件正在访问应用程序上下文
Heres the component were im accessing the apps context
// Dashboard header containing users-name/logout button
export default function Header({ context }) {
const classes = useStyles();
const history = useHistory();
// logs user out and redirects them to '/'
const logout = async () => {
await logoutUser();
context.actions.handleLogout();
history.replace("/");
};
return (
<Container maxWidth={false} className={classes.header}>
<Container>
{/* contacts banner */}
<Grid className={classes.headerContainer} container alignItems="center">
{/* User Icon */}
<Grid item className={classes.headerItem}>
<AccountCircle fontSize="large" />
</Grid>
{/* Users Name */}
<Grid
item
className={`${classes.headerName} ${classes.headerItem}`}
>
<Typography variant="button"> {context.isAuthenticated.name} </Typography>
</Grid>
{/* Logout Button */}
<Grid item>
<Button
style={{ color: "white" }}
className={classes.logoutBtn}
size="large"
onClick={logout}
>
logout
</Button>
</Grid>
</Grid>
</Container>
</Container>
);
}
当使用 console.log(context.isAuthenticated.name)
时,它会打印 2 undefined.但是一旦我刷新页面,就会只打印用户名.所以我的问题是,为什么它只能在刷新页面后才能正常工作,而不是在第一次渲染时才能正常工作.
when using console.log(context.isAuthenticated.name)
it prints 2 undefined. but as soon as I refresh the page, the users-name is printed only. So my question is, why would it only work fine after refreshing the page, instead of when first rendering it.
推荐答案
您需要在发生更改后重新运行 useEffect
.您使用空数组作为第二个参数的效果相当于 componentDidMount()
.因此您需要告诉何时重新渲染.您可以通过执行以下操作来做到这一点.
You need to rerun your useEffect
after there is a change. You use effect with the empty array as second argument is the equivalent of componentDidMount()
.Therefore you need to tell when to re-render. You can do this by doing the following.
useEffect(() => {
onLoad();
},[isAuthenticated]);
这篇关于React 上下文在第一次登录时返回 undefined,但在页面刷新时有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!