React上下文在首次登录时返回未定义,但可用于页面刷新

问题描述 投票:0回答:1

我正在学习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个未定义。但是刷新页面后,只会打印用户名。所以我的问题是,为什么刷新页面后它才可以正常工作,而不是第一次呈现它时。

javascript reactjs react-context
1个回答
0
投票

更改后,您需要重新运行useEffect。将空数组作为第二个参数使用effect,它等于componentDidMount()。因此,您需要告诉何时重新渲染。您可以执行以下操作。

useEffect(() => {
    onLoad();
  },[isAuthenticated]);
© www.soinside.com 2019 - 2024. All rights reserved.