【发布时间】:2021-06-25 01:30:33
【问题描述】:
我有 MERN 应用程序,它使用带有 jwt 的仅 http cookie 作为身份验证。我在 React 中创建了一个提供程序来保存用户信息。前端也有受保护的路线。在后端,如果存在 cookie,我有一个返回当前用户的路由,否则我将用户设置为 null。当应用程序启动、刷新或用户更改时,我会进行此调用。一切正常。
当我刷新页面或使用 url 栏手动导航到某个页面时出现问题。因为在这两种情况下,应用程序都会在很短的时间内刷新用户,直到获取完成为止。结果,我总是被重定向到主页,而不是我刷新或输入的页面。我尝试设置“正在加载”状态,但它仅适用于 App 组件。
示例:我在“/details/1234”上单击刷新,然后被发送回“/”。
有没有办法解决这个问题?也许路由器中的一些更改或强制 React 在获取完成之前不做任何事情?提前致谢。
这是我的提供商的代码:
import { createContext, useEffect, useState } from 'react';
export const AuthContext = createContext();
function AuthContextProvider(props) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function initialUser() {
try {
const response = await fetch(`/api/users/profile`, {
headers: {
"Content-Type": "application/json"
},
method: "GET",
credentials: 'include'
});
setLoading(false);
const userData = await response.json();
return userData.message ? setUser(null) : setUser(userData)
} catch (error) {
console.log(error);
}
}
if (!user) {
initialUser();
}
}, [user]);
return (
<AuthContext.Provider value={{ user, loading, setUser }}>
{props.children}
</AuthContext.Provider>
)
}
export default AuthContextProvider
这是应用程序组件的代码。 App Component 由 Provider 和 Router 封装在 index.js 中
import { useContext } from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import './App.css';
import { AuthContext } from './context/AuthContext';
import Navigation from './components/Navigation/Navigation';
import Footer from './components/Footer/Footer';
import Homescreen from './components/HomeScreen/HomeScreen';
import LandingScreen from './components/LandingScreen/LandingScreen';
import SignScreen from './components/SignScreen/SignScreen';
import Search from './components/Search/Search';
import Genres from './components/Genres/Genres';
import Details from './components/Details/Details';
import Watch from './components/Watch/Watch';
import Profile from './components/Profile/Profile';
function App() {
const { user, loading } = useContext(AuthContext);
return (
!loading
? <div className="App">
<Navigation user={user} />
<Switch>
<Route exact path="/" render={() => (!user ? <LandingScreen /> : <Homescreen />)} />
<Route path="/sign-in" render={() => (!user ? <SignScreen /> : <Redirect to="/" />)} />
<Route path="/sign-up" render={() => (!user ? <SignScreen /> : <Redirect to="/" />)} />
<Route path="/profile" render={() => (!user ? <Redirect to="/sign-in" /> : <Profile />)} />
<Route path="/search" render={() => (!user ? <Redirect to="/sign-in" /> : <Search />)} />
<Route path="/movies/:genre" render={() => (!user ? <Redirect to="/sign-in" /> : <Genres />)} />
<Route path="/details/:id" render={() => (!user ? <Redirect to="/sign-in" /> : <Details />)} />
<Route path="/watch/:id" render={() => (!user ? <Redirect to="/sign-in" /> : <Watch />)} />
</Switch>
<Footer />
</div>
: null
);
}
export default App;
【问题讨论】:
-
你可以实际上使用那个加载状态。而且我建议创建一个“经过身份验证的路由”组件,这样你就不会重复自己。
-
实际使用它是什么意思?我试过 "
!loading ? (!user ? : ) : null)} />" 但结果相同。 -
哦,开枪,对,你正在使用它,但更进一步。您在更新
AuthContextProvider中的用户状态之前设置了loading false。
标签: javascript node.js reactjs express react-router-dom