我对 Remix 还很陌生,可能没有正确掌握整个概念。 我想要实现的目标如下: 我想要一个显示在 /apicheck 上的端点,这需要知道用户已通过身份验证才能访问。
此外,我有一个 /dashboard,它也应该在某处显示 apicheck 内容。
我有 dotnet mvc 背景,所以最接近的是 ViewComponents。
我的结构是这样的:
routes
- dashboard.tsx
- apicheck.tsx
apicheck.tsx 看起来像这样
export const loader: LoaderFunction = async ({ request }) => {
console.log('apicheck loader called');
var user = await authenticator.isAuthenticated(request, {
failureRedirect: "/account/login",
});
let message = 1;
return json({ message })
};
export default function Apicheck() {
console.log("Apicheck component rendered");
const { message } = useLoaderData<typeof loader>();
return (
<div>
{ message }
</div>
);
}
现在是dashboard.tsx
export const loader: LoaderFunction = async ({ request }) => {
console.log('Dashboard loader called');
var user = await authenticator.isAuthenticated(request, {
failureRedirect: "/account/login",
});
return user;
};
export default function Dashboard() {
console.log("Dashboard component rendered");
return (
<div>
<h1>Dashboard</h1>
<Apicheck /> // here I call the other route.
</div>
);
}
问题是,当我将 Apicheck 作为组件调用时,它永远不会调用加载器,这是有道理的,因为我只调用渲染的部分。
最后的问题是,如何将 Apicheck 路由注入到 Dashboard 路由中并显示出来?
编辑: 让我解释一下我的理由。我本质上想要的是可以在任何地方使用的独立组件。例如,假设我们有一个语言选择器,需要从后端读取某些内容,以便在下拉列表中显示要显示的语言。 该元素将放置在布局内的导航上。 目前,我无法使用 Remix 标准制作这样的组件,如果我尝试仅使用 React,我将无法访问
authenticator
。希望这有帮助!
欢迎来到混音!路由需要一些时间来适应。你有几个选择,我想要的一个是提取
Apicheck
作为一个需要 props 的组件,比方说 message
,以及在加载器中检索该消息的功能。然后在apicheck.tsx
中重复使用它:
export default function ApicheckRoute() {
console.log("Apicheck route rendered");
const { message } = useLoaderData<typeof loader>();
return <Apicheck message={message} />;
}
并且在
dashboard.tsx
中,您在加载器中检索消息并将消息传递给 Apicheck
。
解决此问题的另一种方法是使用包含两条路线的无路径布局路线:
routes
- _auth.tsx
- _auth.dashboard.tsx
- _auth.apicheck.tsx
通过这种方式,您可以将通用加载器注入到两条路线中。
_auth.tsx
是布局路线,它包含您的加载程序并通过您的子路线 Outlet
:
export const loader: LoaderFunction = async ({ request }) => {
console.log('auth layout loader called');
var user = await authenticator.isAuthenticated(request, {
failureRedirect: "/account/login",
});
let message = 1;
return json({ message })
};
export default function AuthLayout() {
return <Outlet />;
}
现在你的
_auth.apicheck.tsx
看起来会有所不同,它应该始终使用 _auth.tsx
的加载器的输出,方法是使用 useRouteLoaderData()
:
export default function Apicheck() {
console.log("Apicheck component rendered");
const { message } = useRouteLoaderData<typeof authLoader>('_auth');
return (
<div>
{ message }
</div>
);
}
只要您从
Apicheck
路线内渲染 _auth.*
,它就应该实现您正在寻找的可重用性。
但这并不理想,因为
authenticator.isAuthenticated()
将被调用两次 😬 而且像这样共享默认路由导出有点不传统,这就是为什么我会选择第一个选项,但你可以使该调用更好。