我有一个受保护的路由组件,它主要处理以下几项任务:
- 使用Auth0授权用户。
- 检查存储是否为空,然后向后端API请求用户数据。
- 传递函数,将访问令牌返回给axios拦截器,以便所有请求都有一个承载令牌附加到其头部。
- 现在,我需要添加更多的API请求,以便在应用加载时获取数据。
是否可以将所有这些逻辑都放在受保护的路由组件中?
受保护路由.tsx
const ProtectedRoute = () => {
const dispatch = useAppDispatch();
const location = useLocation();
const { isAuthenticated, isLoading, getAccessTokenSilently } = useAuth0();
const user = useAppSelector((state) => state.user);
useEffect(() => {
const fetchUser = async () => {
try {
await dispatch(getUser()); // here will be more dispatches for fetching data from backend
} catch (e) {}
};
if (isAuthenticated && !user) {
fetchUser();
}
}, [dispatch, isAuthenticated, user]);
useEffect(() => {
const getAccessToken = async () => {
try {
const token = await getAccessTokenSilently();
return Promise.resolve(token);
} catch (e) {
console.log('getAccessToken error:', e);
}
};
httpService(getAccessToken);
}, [getAccessTokenSilently]);
if (isLoading || (!user && isAuthenticated)) {
return <Loader areaLoader />;
}
if (isLoading) {
return <Loader areaLoader />;
}
return isAuthenticated ? <Outlet /> : <Navigate to="/auth" state={{ from: location }} replace />;
};
在App.tsx中,我有一个巨大的路由器,在我看来,放置所有这些逻辑的唯一地方是受保护的路由组件,或者可能是BaseLayout组件:
const router = createBrowserRouter([
{
element: <AuthProvider />,
children: [
{
element: <ProtectedRoute />,
children: [
{
element: <BaseLayout />,
children: [
{
index: true,
element: <ProjectsPage />,
},
{
path: PATHS.faces,
element: <FacesPage />,
},
{
path: PATHS.files,
element: <FilesPage />,
children: [
// some children
],
},
// some other routes
],
},
],
},
{
path: PATHS.auth,
element: <AuthPage />,
},
],
},
]);
基本布局.tsx
const BaseLayout = () => {
return (
<Stack direction={'row'} gap={32}>
<Sidebar />
<Box>
<Outlet />
</Box>
</Stack>
);
};
我尝试将获取数据逻辑移到App.tsx,但没有获取任何数据。我认为是因为这个原因(isAuthenticated来自Auth0钩子,当App.tsx加载时它为false):
if (isAuthenticated && !user) {
dispatch(fetchUser());
dispatch(fetchRawMedias());
}
React Router v6加载程序出现问题
AuthProvider在页面上对Auth0发出重新加载请求以获取令牌。然后令牌附加到所有标头请求。问题是在页面重新加载时,React Router加载程序在Auth0之前触发...它发送标头中没有令牌的请求。如何处理此问题?
1条答案
按热度按时间ee7vknir1#
对于这样的情况,我通常会采用与声明变量相同的做法,即尽可能地将声明 * 下移 * 以限制它们的作用域。
示例
在何处声明React状态函数类似地取决于状态的作用域和需要访问它的对象。
这里的想法是将声明 * 向上推**到必要的程度*。
那么,“正确的地方”在哪里呢?
保持获取逻辑和状态的“正确”位置是在满足需求的情况下尽可能限制其范围的位置。随着用例和特性的变化,这可能会在应用程序的生命周期中发生变化。
如果你有“全局应用状态”,应该在应用挂载时获取和管理,这听起来像是它应该/应该位于应用的ReactTree中相当高的位置。
是否可以将所有这些逻辑都放在受保护的路由组件中?
这个问题的答案是,你 * 可以 * 这样做,但我建议创建一个新的提供者/布局组件,专门用于状态管理和数据获取,主要是出于希望保持良好的“关注点分离”和single responsibility principle。换句话说,我不建议让
ProtectedRoute
做更多的事情,而不仅仅是保护路由,或者让BaseLayout
做更多的UI布局。提供程序组件和放置示例:
第一个