React 上下文在第一次登录时返回 undefined,但在页面刷新时有效 [英] React context returns undefined on first login, but works on page refresh

查看:43
本文介绍了React 上下文在第一次登录时返回 undefined,但在页面刷新时有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆