useContext React JS中的延迟



在我的React应用程序中,当用户登录时,会生成一个令牌(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 });
}
});

编辑:对不起,我没有很好地阅读你的问题。是的,您所面对的是非常正常的,因为在第一次渲染时,您没有登录,因此Log out按钮将显示为Log in。你能做的是:

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

最新更新