【问题标题】:Delay in useContext React JS延迟useContext React JS
【发布时间】:2021-03-19 10:46:29
【问题描述】:

在我的 React App 中,当用户登录时,会生成一个令牌 (JWT),然后将其存储在 LocalStorage 中。

一切完成后,为了维护不同路由的用户登录,我使用了useContext。

我想在用户登录时显示注销按钮(实际上它会出现,但在 2 秒后)简而言之,我可以看到登录/注册按钮,2 秒后它会显示注销按钮。

这是我的代码:

Main.js

export default function Main() {

const [userData,setUserData] = useState(
  {token:undefined,
  user:undefined,}
);

useEffect(()=>{
const checkLoggedIn = async() =>{
  const token = localStorage.getItem("auth-token");
  if(token===null) {localStorage.setItem("auth-token","");
  token = "";}
  const tokenRes = await Axios.post("http://localhost:5000/user/tokenIsValid",
  null,
  {headers:{"x-auth-token":token}})
if(tokenRes.data){
  const userRes = await Axios.get("http://localhost:5000/user/",{headers:{"x-auth-token":token}})
  setUserData({
    token,
    user:userRes.data
  })
}
  };

  checkLoggedIn();
}

,[])



  return (
    <BrowserRouter>
      <UserContext.Provider value={{userData,setUserData}}>
      <ThemeProvider theme={theme}>
      
        <Navbar />

        <Switch>
          <Route exact path="/" component={Home} />

          <Route exact path="/login" component={Login} />
          <Route exact path="/register" component={Register} />
                  <Route exact path="/recover" component={Recover} />
          <Route exact path="/privacy-policy" component={PrivacyPolicy} />
          <Route
            exact
            path="/terms-of-service"
            component={TermsAndConditions}
          />
          <Route exact path="/contact" component={Contact} />
          <Route exact path="/faqs" component={FAQs} />
          <Route component={Error} />
        </Switch>

        <myFooter />
        </ThemeProvider>
        </UserContext.Provider>
      
    </BrowserRouter>
  );
}

那么这是我的 Navbar.js

export default function Navbar(){
  const { userData,setUserData } = useContext(UserContext);
  const classes = useStyles();
  const logout = () =>{
    setUserData({
      token:undefined,
      user:undefined
    })
    localStorage.setItem("auth-token","")
  }
  return(
<>

<AppBar position="static" color="transparent">
  <Toolbar>
    <Typography  className={classes.doBold}>
      <Link to="/" className={classes.noLinkStyle}><img src={require('../images/logo.png')} height="auto" width="150px" className={classes.AlignVertical} alt="Logo"/></Link>
    </Typography>
    <ButtonGroup size="small" variant="outlined" color="secondary">
      {
        userData.user!==undefined?<myLoginMenu  style={{marginRight:'20px'}}/>:<> <Link to="/login" className={classes.noLinkStyle}><myButton variant="contained" content="Login" icon="login"/></Link>
        <Link to="/register" className={classes.noLinkStyle}><myButton variant="contained" primary content="Register" icon="register" /></Link></>
      }



</ButtonGroup>
  </Toolbar>

</AppBar>

</>
  )
}

最后是 UserContext.js

import {createContext} from 'react';
export default createContext(null);

这是我的登录路径

router.get("/login", async (req, res) => {
  try {
    const { email, password } = req.body;
    if (!email || !password) {
      return res.status(400).json({ msg: "Something is missing." });
    }
    const student = await Student.findOne({ email: email });
    if (!student)
      return res
        .status(400)
        .json({ msg: "No account reigstered with this email." });

    const isMatch = await bcrypt.compare(password, student.password);
    if (isMatch) {
      
      const token = jwt.sign({id:student._id},process.env.JWT_TOKEN)
      res.json({
          token,
          user:{
              id:student._id
          }
      })
    } else return res.status(400).json({ msg: "Incorrect Password" });
  } catch (error) {
    res.status(500).json({ errorReceived: error });
  }
});

【问题讨论】:

  • 如果我完全理解您的问题,我认为您可能还需要向我们展示Login 组件。基本上,在您登录后,它会切换两个不同的页面,但 UI 直到两秒钟后才反映您已登录,我假设。不过,如果没有看到 Login 组件,我无法确定。
  • 至于如果用户在两秒后已经登录则呈现为未登录,这可能是因为您有几个异步函数和方法正在运行(useEffect 和各种 API 调用),但您确实这样做了在他们完成检索某些信息之前不要阻止渲染,从而导致视觉错误。
  • 嗨@CoryHarper 我刚刚通过 /login 路由添加了登录(发布请求)。我已经用新代码更新了这个问题。请检查。
  • 抱歉,我指的是 React Login 组件。

标签: reactjs react-router jwt context-api use-context


【解决方案1】:

已编辑:抱歉,我没有很好地阅读您的问题。是的,你所面对的很正常,因为在第一次渲染时,你没有登录,所以Log out 按钮看起来是Log in。 你可以做的是:

  1. 添加服务器端渲染器。因此,当您的应用程序在服务器端运行时,它会运行身份验证以获取用户数据,然后返回到客户端。
  2. 隐藏(或为Log in/Log out 按钮设置动画,直到useEffect 完成运行)以便用户体验更流畅。

【讨论】:

  • 添加这一行后,显示 userRes 未定义。
  • 我会选择 SSR,但我在 YouTube 上看到的视频与我的模式相同。在他的视频中,登录/注册按钮按预期工作正常。但对我来说不是。
  • 你能把那个视频的链接发给我吗?
  • 视频 1:youtube.com/watch?v=sWfD20ortB4 -> 用于上下文。视频 2:youtube.com/watch?v=bppuE6rbO1c -> 用于显示隐藏登录/注册。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-28
  • 1970-01-01
  • 2021-05-30
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多