T
TanStack7mo ago
genetic-orange

How to access individual customer by ID after a search with TanStack Query?

Hi, working on a React Native app with Expo Router + TanStack Query and could use some advice on caching patterns. what i have:
const searchCustomersQueryOptions = (search: string) =>
queryOptions({
queryKey: ["customers", search],
queryFn: () => getCustomers(search),
});

export const useSearchCustomers = (search: string) => {
return useQuery(searchCustomersQueryOptions(search));
};
const searchCustomersQueryOptions = (search: string) =>
queryOptions({
queryKey: ["customers", search],
queryFn: () => getCustomers(search),
});

export const useSearchCustomers = (search: string) => {
return useQuery(searchCustomersQueryOptions(search));
};
In another screen, I allow selecting a customer and passing only their id back. Later, I want to fetch the full customer data using just the ID, ideally from the query cache . Because customers are cached under ['customers', search], I can't access them directly by ['customer', id] later — unless I search thru that key wich is meh.. any suggestion? Idk if this is right but ideally i would need ['customer', customer.id]
9 Replies
genetic-orange
genetic-orangeOP7mo ago
I guess i could just store selected customer inside client state but because it comes from backend i would like to simply retrieve it from tanstack --- Here is what im currently doing in the meantime: i still cache the search result. whenever i do select a user on a search list, i cache the selected customer item then can retrieve elsewhere.
const handleSelect = (customer: CustomerItem) => {
queryClient.setQueryData(["customer", customer.id], customer);

const params = {
selectedCustomerId: customer.id.toString(),
timestamp: Date.now().toString(),
};

console.log("Sending params:", params);
router.dismissTo({
pathname: "/upsert-job-modal",
params,
});
};
const handleSelect = (customer: CustomerItem) => {
queryClient.setQueryData(["customer", customer.id], customer);

const params = {
selectedCustomerId: customer.id.toString(),
timestamp: Date.now().toString(),
};

console.log("Sending params:", params);
router.dismissTo({
pathname: "/upsert-job-modal",
params,
});
};
retrieval in a different component (expo)
useEffect(() => {
if (params.selectedCustomerId) {
const customerData = queryClient.getQueryData<CustomerItem>([
"customer",
+params.selectedCustomerId,
]);
if (customerData) {
const name = `${customerData.firstName} ${customerData.lastName}`;
setSelectedCustomer({
id: customerData.id,
name: name,
initials: `${customerData.firstName[0]}${customerData.lastName[0]}`,
});
setValue("clientId", customerData.id);
}
}
}, [params.selectedCustomerId, params.timestamp]);
useEffect(() => {
if (params.selectedCustomerId) {
const customerData = queryClient.getQueryData<CustomerItem>([
"customer",
+params.selectedCustomerId,
]);
if (customerData) {
const name = `${customerData.firstName} ${customerData.lastName}`;
setSelectedCustomer({
id: customerData.id,
name: name,
initials: `${customerData.firstName[0]}${customerData.lastName[0]}`,
});
setValue("clientId", customerData.id);
}
}
}, [params.selectedCustomerId, params.timestamp]);
genetic-orange
genetic-orangeOP7mo ago
No description
like-gold
like-gold7mo ago
Hi there, do customers & customers, id endpoints return the same customer object?
genetic-orange
genetic-orangeOP7mo ago
hi denis, lets assume they do if they didnt they there would be not point to try to use the cached data as it would be missing info right?
like-gold
like-gold7mo ago
The thing is, that if they return the same customer object you may populate customer, id cache from the customers endpoint, but if they don't this won't work yes
genetic-orange
genetic-orangeOP7mo ago
but assuming they do, is what i did correct? navigate to list of customers with search input [customers, search] which would cache the result per search keyword. now when going back to previous page i want to retrieve the selected user. I know its cached but idk where because its cached under a search keyword and not a flat list So what i did is as im selecting the user (within the customers search page) i also manually cache the selected customer to [customer, id so i can get it using the selectedId param in the cache:
const customerData = queryClient.getQueryData<CustomerItem>([
"customer",
+params.selectedCustomerId,
]);
const customerData = queryClient.getQueryData<CustomerItem>([
"customer",
+params.selectedCustomerId,
]);
like-gold
like-gold7mo ago
Yeah, you can do it. I don't see any problems with this approach.
genetic-orange
genetic-orangeOP7mo ago
Great ty
like-gold
like-gold7mo ago
no problem 🙂

Did you find this page helpful?