I'm currently stuck in a situation that's proving to be quite challenging.
Working on an ambitious NextJS 14 application, I've encountered the need to pull data from an external GraphQL API.
Specifically, I have a page dedicated to displaying our valuable customers.
To retrieve this customer data, I rely on a server action named get-customers.ts
:
"use server";
import { RequestResult } from "@/common/types/request.interface";
import { request } from "@/common/utils/http/request";
import {
CustomersDocument,
CustomersQuery,
CustomersQueryVariables,
} from "@/graphql/generated/graphql";
export default async function getCustomers(
variables: CustomersQueryVariables
): Promise<RequestResult<CustomersQuery>> {
console.log("About to query customers");
const { result }: { result: RequestResult<CustomersQuery> } = await request<
CustomersQuery,
CustomersQueryVariables
>(CustomersDocument, variables, ["customers"]);
return result;
}
Within this server action, I utilize the helper method 'request' for fetching data and also pass along certain tags.
Then comes my page. To leverage the capabilities of pagination, filtering, and sorting provided by the external API, I must re-query the data when any filters change. Hence, I employ the use of useEffect
and declare my page as a "use client"
page.
Here's a snippet of my page code (with irrelevant parts omitted):
"use client";
export default function Customers() {
// Code for handling filters, pagination, etc.
// ...
}
From what you can see, the page heavily relies on client-side functionalities.
Moving over to the <CreateCustomerSheet />
component, it houses a form that triggers another server action responsible for creating new customers:
export default async function createCustomer(
_prevState: FormState,
data: FormData
): Promise<any> {
try {
// Logic for parsing and validating the form data
// ...
// Making the actual API call to create a new customer
// ...
} catch (error) {
// Handling errors gracefully
// ...
}
}
Despite seeing successful creation logs in the server, indicating that everything is going smoothly including tag revalidation, the query for refreshing the data does not seem to trigger again.
My Attempts So Far
In an attempt to resolve this issue, I experimented with removing all client-side features from my page.tsx
component to transform it into a server component. Surprisingly, upon creating a new customer, I noticed immediate data updates.
What I Need Help With
How can I maintain the essence of a server component while ensuring that user input such as filters, pagination, and sorting are seamlessly updated? It's puzzling me how to address this challenge effectively.
While I've come across examples where data is queried within a server component before being passed down to a client component, I'm struggling to navigate this specific scenario where dynamic user interactions play a crucial role in updating the displayed data.