刷新页面时反应上下文未定义
React context undefined when refreshing page
我想创建一个只有经过身份验证的用户才能访问的受保护路由。它工作 BUT 当我刷新页面时上下文未定义并将用户重定向到登录页面。我真的不明白为什么会这样。
刷新页面后的控制台日志
App.js
import React, { useState, useEffect } from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Axios from "axios";
import Home from "./components/pages/Home";
import LandingPage from "./components/pages/LandingPage";
import { ProtectedRoute } from "./components/auth/ProtectedRoute";
import UserContext from "./context/UserContext";
import "./style.css";
export default function App() {
const [userData, setUserData] = useState({
token: undefined,
user: undefined,
});
const checkLoggedIn = async () => {
let token = localStorage.getItem("auth-token");
if (token === null) {
localStorage.setItem("auth-token", "");
token = "";
}
const tokenRes = await Axios.post(
"http://localhost:5000/users/tokenIsValid",
null,
{ headers: { "x-auth-token": token } }
);
if (tokenRes.data) {
const userRes = await Axios.get("http://localhost:5000/users/", {
headers: { "x-auth-token": token },
});
setUserData({
token,
user: userRes.data,
});
}
};
useEffect(() => {
console.log('useEffect called');
checkLoggedIn();
}, []);
return (
<>
<BrowserRouter>
<UserContext.Provider value={{ userData, setUserData }}>
<Switch>
<Route exact path="/" component={LandingPage} />
<ProtectedRoute exact path="/home" component={Home} />
</Switch>
</UserContext.Provider>
</BrowserRouter>
</>
);
}
ProtectedRoute.js
import React, { useContext } from "react";
import UserContext from "../../context/UserContext";
import { Route, Redirect } from "react-router-dom";
export const ProtectedRoute = ({
component: Component,
...rest
}) => {
const { userData } = useContext(UserContext);
return (
<Route
{...rest}
render={props => {
console.log("USERDATA " + userData.user)
console.log("TOKEN " + localStorage.getItem("auth-token"))
if (userData.user) {
return <Component {...props} />;
} else {
return (
<Redirect
to={{
pathname: "/",
state: {
from: props.location
}
}}
/>
);
}
}}
/>
);
};
编辑
过了一会儿我弄清楚了问题,这个问题在
中有解释
过了一会儿我发现了问题,这个问题在这个问题中有解释
这是我的解决方案,效果很好。
App.js
export default function App() {
const [userData, setUserData] = useState({
isLoggedIn: false,
isLoading: true,
token: undefined,
user: undefined
});
const checkLoggedIn = async () => {
const tokenRes = await validateToken();
if (tokenRes.data) {
const userRes = await getUser();
let token = localStorage.getItem("auth-token");
setUserData({
token,
user: userRes.data,
isLoggedIn: true,
isLoading: false
});
}
};
useEffect(() => {
console.log('useEffect called');
checkLoggedIn();
}, []);
console.log("APPPPPP")
return (
<>
<BrowserRouter>
<UserContext.Provider value={{ userData, setUserData }}>
<Switch>
<Route exact path="/" component={LandingPage} />
<ProtectedRoute exact path="/home" component={Home} />
</Switch>
</UserContext.Provider>
</BrowserRouter>
</>
);
}
ProtectedRoute.js
import React, {useContext} from "react";
import { Route, Redirect } from "react-router-dom";
import UserContext from "../../context/UserContext";
const ProtectedRoute = ({ component: Comp, path, ...rest }) => {
const { userData } = useContext(UserContext);
console.log(userData.isLoggedIn);
return (
<Route path={path} {...rest}
render={props => {
return userData.isLoggedIn ? (<Comp {...props} />) : (userData.isLoading ? 'Loading...' : <Redirect to="/" />)
}}
/>
);
};
export default ProtectedRoute;
我想创建一个只有经过身份验证的用户才能访问的受保护路由。它工作 BUT 当我刷新页面时上下文未定义并将用户重定向到登录页面。我真的不明白为什么会这样。
刷新页面后的控制台日志
App.js
import React, { useState, useEffect } from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Axios from "axios";
import Home from "./components/pages/Home";
import LandingPage from "./components/pages/LandingPage";
import { ProtectedRoute } from "./components/auth/ProtectedRoute";
import UserContext from "./context/UserContext";
import "./style.css";
export default function App() {
const [userData, setUserData] = useState({
token: undefined,
user: undefined,
});
const checkLoggedIn = async () => {
let token = localStorage.getItem("auth-token");
if (token === null) {
localStorage.setItem("auth-token", "");
token = "";
}
const tokenRes = await Axios.post(
"http://localhost:5000/users/tokenIsValid",
null,
{ headers: { "x-auth-token": token } }
);
if (tokenRes.data) {
const userRes = await Axios.get("http://localhost:5000/users/", {
headers: { "x-auth-token": token },
});
setUserData({
token,
user: userRes.data,
});
}
};
useEffect(() => {
console.log('useEffect called');
checkLoggedIn();
}, []);
return (
<>
<BrowserRouter>
<UserContext.Provider value={{ userData, setUserData }}>
<Switch>
<Route exact path="/" component={LandingPage} />
<ProtectedRoute exact path="/home" component={Home} />
</Switch>
</UserContext.Provider>
</BrowserRouter>
</>
);
}
ProtectedRoute.js
import React, { useContext } from "react";
import UserContext from "../../context/UserContext";
import { Route, Redirect } from "react-router-dom";
export const ProtectedRoute = ({
component: Component,
...rest
}) => {
const { userData } = useContext(UserContext);
return (
<Route
{...rest}
render={props => {
console.log("USERDATA " + userData.user)
console.log("TOKEN " + localStorage.getItem("auth-token"))
if (userData.user) {
return <Component {...props} />;
} else {
return (
<Redirect
to={{
pathname: "/",
state: {
from: props.location
}
}}
/>
);
}
}}
/>
);
};
编辑
过了一会儿我弄清楚了问题,这个问题在
过了一会儿我发现了问题,这个问题在这个问题中有解释
这是我的解决方案,效果很好。
App.js
export default function App() {
const [userData, setUserData] = useState({
isLoggedIn: false,
isLoading: true,
token: undefined,
user: undefined
});
const checkLoggedIn = async () => {
const tokenRes = await validateToken();
if (tokenRes.data) {
const userRes = await getUser();
let token = localStorage.getItem("auth-token");
setUserData({
token,
user: userRes.data,
isLoggedIn: true,
isLoading: false
});
}
};
useEffect(() => {
console.log('useEffect called');
checkLoggedIn();
}, []);
console.log("APPPPPP")
return (
<>
<BrowserRouter>
<UserContext.Provider value={{ userData, setUserData }}>
<Switch>
<Route exact path="/" component={LandingPage} />
<ProtectedRoute exact path="/home" component={Home} />
</Switch>
</UserContext.Provider>
</BrowserRouter>
</>
);
}
ProtectedRoute.js
import React, {useContext} from "react";
import { Route, Redirect } from "react-router-dom";
import UserContext from "../../context/UserContext";
const ProtectedRoute = ({ component: Comp, path, ...rest }) => {
const { userData } = useContext(UserContext);
console.log(userData.isLoggedIn);
return (
<Route path={path} {...rest}
render={props => {
return userData.isLoggedIn ? (<Comp {...props} />) : (userData.isLoading ? 'Loading...' : <Redirect to="/" />)
}}
/>
);
};
export default ProtectedRoute;