local-storage - 反应上下文的问题。页面刷新时上下文丢失
问题描述
我对上下文有点困惑,而且我是 ReactJS 的新手。我尝试实现登录机制并拥有一些受保护的路由,但是当我刷新页面时,上下文丢失了,尽管我将所需的一切都保存在本地存储中。这是我所做的。
语境:
import {createContext} from 'react'
export const AuthContext = createContext({
isLoggedIn: false,
userId:null,
role:null,
username:null,
token: null,
login: () => {},
logout: () => {}
})
授权钩子:
import { useState, useCallback, useEffect } from 'react';
import jwt_decode from "jwt-decode";
let logoutTimer
export const useAuth = () => {
const [role, setRole] = useState(null)
const [token, setToken] = useState(null)
const [tokenExpirationDate, setTokenExpirationDate] = useState()
const [username, setUsername] = useState(null)
const [userId, setUserId] = useState(null)
const [isLoggedIn, setIsLoggedIn] = useState(false)
const login = useCallback((user, serverToken) => {
if (localStorage.getItem('user')){
let user = JSON.parse(localStorage.getItem('user'))
let token = user.token
setToken(token)
let decoded = jwt_decode(token)
console.log(decoded)
console.log(decoded.userId)
console.log(decoded.role)
console.log(decoded.username)
setUserId(decoded.userId)
setRole(decoded.role)
setUsername(decoded.username)
setIsLoggedIn(user.isLoggedIn)
}
else {
let expirationDate = new Date(new Date().getTime() + 1000 * 60 * 60)
setTokenExpirationDate(expirationDate)
setToken(serverToken)
setUsername(user.username)
setUserId(user.userId)
setRole(user.role)
setIsLoggedIn(true)
localStorage.setItem('user',
JSON.stringify({
token: serverToken,
isLoggedIn:true,
expiration: expirationDate.toISOString()
}))
}
}, [])
const logout = useCallback(() => {
setToken(null);
setRole(null)
setTokenExpirationDate(null);
localStorage.removeItem('user');
}, [])
useEffect(() => {
if (token && tokenExpirationDate) {
const remainingTime = tokenExpirationDate.getTime() - new Date().getTime();
logoutTimer = setTimeout(logout, remainingTime);
} else {
clearTimeout(logoutTimer);
}
}, [token, logout, tokenExpirationDate]);
useEffect(() => {
const storedData = JSON.parse(localStorage.getItem('user'));
if (
storedData &&
storedData.token &&
new Date(storedData.expiration) > new Date()
) {
//recheck how to implement this
login( storedData.token, username);
}
}, [login]);
useEffect(()=>{
if (localStorage.getItem('user')){
let user = JSON.parse(localStorage.getItem('user'))
let token = user.token
setToken(token)
let decoded = jwt_decode(token)
console.log(decoded)
console.log(decoded.userId)
console.log(decoded.role)
console.log(decoded.username)
setUserId(decoded.userId)
setRole(decoded.role)
setUsername(decoded.username)
setIsLoggedIn(user.isLoggedIn)
}
},[])
return { token, role, login, logout, username, userId, isLoggedIn };
}
应用程序.js
function App() {
const {token, role, login, logout, username, userId, isLoggedIn} = useAuth()
console.log("INSIDE APP")
console.log(token)
console.log(isLoggedIn)
return (
<AuthContext.Provider value={{
isLoggedIn: isLoggedIn,
userId: userId,
role: role,
username:username,
token: token,
login: login,
logout: logout
}}>
<Container style={backgroundStyle}>
<SidebarPage />
<Switch>
<AuthenticatedRoute path="/employeetab" component={EmployeeTab}/>
<AuthenticatedRoute path="/employeeTable" component={EmployeeTable}/>
<AuthenticatedRoute path="/materialsTab" component={Materials}/>
<AuthenticatedRoute path="/worktab" component={WorkTab}/>
<AuthenticatedRoute path="/warehouse" component={InventoryTab}/>
<Route path="/adminPage">
<AdminPage />
</Route>
<AuthenticatedRoute path="/personelTable" component={PersonnelTable}/>
<AuthenticatedRoute path="/sector" component={Sector}/>
<AuthenticatedRoute path="/tools" component={GearTab}/>
<Route path="/not-found">
<NotFound />
</Route>
<AuthenticatedRoute path="/" exact component={Dashboard}/>
<Route path="/login" exact component={LoginComponent}/>
<Redirect to="/not-found" />
</Switch>
</Container>
</AuthContext.Provider>
);
}
export default App;
保护路线:
import React, {useContext} from 'react'
import { Component } from 'react'
import { Route, Redirect } from 'react-router-dom'
import {AuthContext} from "../context/AuthContext";
const AuthenticatedRoute = ({ path, component: Component}) => {
const auth = useContext(AuthContext)
console.log(auth.isLoggedIn)
return (
<Route
path={path}
render={props => {
if (auth.isLoggedIn === false) {
return <Redirect to="/login" />
}
else {
return <Component {...props} />
}
}}
/>
)
}
export default AuthenticatedRoute
当我登录时,一切都按预期工作,直到我刷新我所在的页面。然后,我总是被重定向到 LoginPage。
我什至尝试在 AuthHook 中使用 Effect 从 localStorage 重新加载所有内容。
我在这里缺少什么?提前致谢。
解决方案
推荐阅读
- c++ - 绑定 API 在服务器程序中究竟做了什么
- sql - 如果具有这些名称的表存在,则执行联合
- objective-c - 为什么将此协议添加到此类别会触发编译器警告?
- python - CVXPY:解相等的目标函数
- css - 我需要将样式更改为具有类的 div 内所有出现的锚元素
- docker - Docker API /images/json 总是返回 Containers:-1
- go - go数据结构中的继承
- java - 如何检查 glassfish 上的 http 请求的完整响应时间?
- python - 在python中搜索查询
- speech-to-text - 使用其他数据重新训练 Azure 自定义语音模型