T
TanStack14mo ago
deep-jade

how to refetch with a passed in variable, state is behind

I'm strugging with the best way to handle this. I have a button in my web app that generates an Excel spreadsheet in the backend and sends it to the browser as a download. When the button is clicked, it passes an id to a function so it knows which list to go create a spreadsheet of. I am saving that id into state, but that is not working because of how state works and it is always behind by a click. The function that runs on the click is this one:
const createXLSXFromPriceList = (id: string) => {
console.log({id});
setPriceListToSpreadsheetID(id);
refetch();
};
const createXLSXFromPriceList = (id: string) => {
console.log({id});
setPriceListToSpreadsheetID(id);
refetch();
};
And the useQuery with the refetch:
const {
data: spreadsheetResult,
refetch
}: {
data: string | undefined;
} = useQuery({
queryFn: getPriceListSpreadsheet,
queryKey: ['spreadsheetResult', priceListToSpreadsheetID],
enabled: false,
gcTime: 1
});
const {
data: spreadsheetResult,
refetch
}: {
data: string | undefined;
} = useQuery({
queryFn: getPriceListSpreadsheet,
queryKey: ['spreadsheetResult', priceListToSpreadsheetID],
enabled: false,
gcTime: 1
});
21 Replies
deep-jade
deep-jadeOP14mo ago
What is the best way to handle this so that the query runs with the correct id on click?
correct-apricot
correct-apricot14mo ago
Why is it not a mutation?
deep-jade
deep-jadeOP14mo ago
Its just getting data from the database and creating a spreadsheet with it, should that be a mutation?
correct-apricot
correct-apricot14mo ago
I think a useMutation has some advantages in this scenario
deep-jade
deep-jadeOP14mo ago
ok, will it allow me to send the correct id when I click the button? basically how do I call the useMutation on command passing it a given variable?
correct-apricot
correct-apricot14mo ago
Did you read the documentation?
deep-jade
deep-jadeOP14mo ago
yes, I've looked through it, it quite overwhelming
deep-jade
deep-jadeOP14mo ago
GitHub
How can i useQuery when parameter change by onClick button? · TanSt...
when i have list page, one of lists has id. when i click that one, i want to get info about that id; I use useMutation and my code like this: // Mutation const { mutateAsync: getData } = useGetData...
deep-jade
deep-jadeOP14mo ago
i'll try fetchQuery right in that function. Thanks!
criminal-purple
criminal-purple14mo ago
Would this not work?
const [priceListToSpreadsheetID, setPriceListToSpreadsheetID] = useState<string | null>(null);

const {
data: spreadsheetResult,
} = useQuery({
queryFn: () => {
// use priceListToSpreadsheetID to fetch the proper spreadsheet
},
queryKey: ['spreadsheetResult', priceListToSpreadsheetID],
enabled: !!priceListToSpreadsheetID,
});

// Logic updates priceListToSpreadsheetID
const [priceListToSpreadsheetID, setPriceListToSpreadsheetID] = useState<string | null>(null);

const {
data: spreadsheetResult,
} = useQuery({
queryFn: () => {
// use priceListToSpreadsheetID to fetch the proper spreadsheet
},
queryKey: ['spreadsheetResult', priceListToSpreadsheetID],
enabled: !!priceListToSpreadsheetID,
});

// Logic updates priceListToSpreadsheetID
This is a more declaritive (and intended) way to use useQuery^
deep-jade
deep-jadeOP14mo ago
oh that makes sense! Now how would I set priceListToSpreadsheetID back to null after clicking the button?
criminal-purple
criminal-purple14mo ago
I dont think you want to set it to null. Think about it this way, whatever the value of priceToSpreadsheetID is, useQuery will react to the new state, and give you the new data. So if you have 3 spreadsheets, "a", "b", & "c", if you set priceToSpreadsheetID to "a", useQuery will automatically fetch the spreadsheet for "a". If you want to keep viewing "a", then don't touch priceToSpreadsheetID. But if you want to view "b", then update priceToSpreadheetID to "b" and useQuery will give you the spreadsheet for "b"
deep-jade
deep-jadeOP14mo ago
aw The click generates an excel spreadsheet and downloads it to the browser. So in that circumstance, clicking the same link twice wouldn't do anything the second time.
criminal-purple
criminal-purple14mo ago
Oh so you are not just fetching existing data, but generating a new spreadsheet?
deep-jade
deep-jadeOP14mo ago
yeah, it runs code on my node server to create the spreadsheet from data in the DB and then sends it to the browser
criminal-purple
criminal-purple14mo ago
I see
criminal-purple
criminal-purple14mo ago
criminal-purple
criminal-purple14mo ago
Then the data that is returned from useMutation should be the spreadsheet you just created Let me see if I can create an example
const { mutate, data } = useMutation({
mutationFn: async (spreadsheetId: string) => {
// Generate a new spreadsheet, and return it here
const spreadsheet = await generateSpreadsheet(spreadsheetId)
return spreadsheet
},
})

// data will always be the last spreadsheet that was generated.
// If the mutation has not yet been run, data will be undefined.
console.log(data)

// Run the mutation
mutate("my-spreadsheet-id")
const { mutate, data } = useMutation({
mutationFn: async (spreadsheetId: string) => {
// Generate a new spreadsheet, and return it here
const spreadsheet = await generateSpreadsheet(spreadsheetId)
return spreadsheet
},
})

// data will always be the last spreadsheet that was generated.
// If the mutation has not yet been run, data will be undefined.
console.log(data)

// Run the mutation
mutate("my-spreadsheet-id")
Updated it to be more concise
criminal-purple
criminal-purple14mo ago
This page gives a good explanation on mutations: https://tanstack.com/query/latest/docs/framework/react/guides/mutations
Mutations | TanStack Query React Docs
Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects. For this purpose, TanStack Query exports a useMutation hook. Here's an example of a mutation that adds a new todo to the server:
deep-jade
deep-jadeOP14mo ago
cool, thank you! works beautifully! Appreciate the help!
criminal-purple
criminal-purple14mo ago
Awesome!

Did you find this page helpful?