Is my use of Tanstack Query with server action to fetch data good ?
Unanswered
Orange-tailed bumble bee posted this in #help-forum
Orange-tailed bumble beeOP
I'm trying to migrate an app from the pages router to the app router and I'd like to use server actions instead of using the api folder.
Here's my server action that fetches data:
Then I use this function in a custom Tanstack Query hook:
Then I prefetch it in a server component:
Finally, I call the hooks in my client component:
I'm getting the data in my component but I'd like to know if it's the best way to do it or if there are other ways to fetch the data that would be better performance-wise or with less code ?
I want to keep a loading and error state.
Here's my server action that fetches data:
action.ts
import 'server-only';
type Props = {
tenantId: string;
page: number;
};
export const preload = (body: Props) => {
void getPaginatedNodes(body);
};
export const getPaginatedNodes = cache(async (body: Props) => {
try {
if (!body) {
return { error: 'Tenant not found' };
}
const result = getNodesSchema.safeParse(body);
if (result.success === false) {
const errors = result.error.formErrors.fieldErrors;
return { error: 'Invalid request' + errors };
} else {
const { tenantId, page } = result.data;
const nodes = await prisma.node.findMany({
where: { tenantId: tenantId as string },
orderBy: { createdAt: 'desc' },
skip: page * OFFSET,
take: OFFSET,
include: nodeModel,
});
return nodes;
}
} catch (error) {
return { error: 'Error fetching nodes' };
}
});Then I use this function in a custom Tanstack Query hook:
export const useNodes = (tenantId: string, page: number) => {
const body = { tenantId, page };
return useQuery({
queryKey: [QueryKeys.NODES, tenantId, page],
queryFn: async () => getPaginatedNodes(body),
});
};Then I prefetch it in a server component:
await queryClient.prefetchQuery({
queryKey: [QueryKeys.NODES, me.tenantId, page],
queryFn: () => getAllNodes(me.tenantId, page),
});Finally, I call the hooks in my client component:
const {
data: initialNodes,
isPending,
isError,
error,
} = useNodes(me.tenantId, page);I'm getting the data in my component but I'd like to know if it's the best way to do it or if there are other ways to fetch the data that would be better performance-wise or with less code ?
I want to keep a loading and error state.