我有一个 HOC ProtectedRoute 可以防止未经授权的用户访问某些 URL,它通过 useSelector 检查用户是否获得授权
function ProtectedRoute() {
const dispatch = useDispatch();
const token = localStorage.getItem("refresh");
useEffect(() => {
dispatch(checkAuth(token));
}, [])
const isLoading = useSelector((state: RootState) => state.appReducer.isLoading);
const isAuth = useSelector((state: RootState) => state.userSliceReducer.isAuth);
if (isLoading) {
return <Loader/>
}
return (isAuth ? <Outlet /> : <Navigate to="/login/" replace={true} />)
};
该组件还检查应用程序是否处于加载阶段(isLoading),如果 isLoading == true,则返回 Loader 组件(我知道当然最好将加载检查功能移至单独的 HOC 中,但我离开了以免弄乱文章代码)。ProtectedRoute 在App.tsx中的使用如下:
function App() {
return (
<BrowserRouter>
<Suspense fallback={<Loader/>}>
<Routes>
<Route path='/' element={<ProtectedRoute/>}>
<Route path='/' element={<Layout />}>
// Тут находятся различные Routes, которые не влияют на работу protected route
</Route>
</Route>
<Route path='/login' element={<Login />} />
<Route path='/register' element={<Register />} />
<Route path='/*' element={<NotFoundPage />} />
</Routes>
</Suspense>
</BrowserRouter>
);
}
当您尝试未经授权访问任何路线时,一切正常。但是刷新页面时有一个问题,用户首先看到Loader,然后他被重定向到Login,然后到主Route。我已经尝试向App.tsx添加下载验证功能。并做了以下事情:
<Route path='/' element={isLoading ? <Loader/> : <ProtectedRoute/>}>
但存在一个问题,即状态不断更新,并且两个组件在屏幕上交替闪烁。如何在不违反ProtectedRoute工作原理的情况下解决重启时Login和Loader闪烁的问题?
我通过将加载逻辑移至 App 组件解决了这个问题:
ProtectedRoute 现在看起来像这样: