我正在学习React Context并在HOC上使用它,以便我可以查看用户是否在我的整个应用程序中都已登录。登录后,我从上下文中获取用户名并将其显示在标题中。之前一切正常,但现在突然间,用户首次登录时未显示名称,但刷新页面后便正常显示。
这是我的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>
)
}
}
这里组件正在即时访问应用上下文
// 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个未定义。但是刷新页面后,只会打印用户名。所以我的问题是,为什么刷新页面后它才可以正常工作,而不是第一次呈现它时。
更改后,您需要重新运行useEffect
。将空数组作为第二个参数使用effect,它等于componentDidMount()
。因此,您需要告诉何时重新渲染。您可以执行以下操作。
useEffect(() => {
onLoad();
},[isAuthenticated]);