Daniel
Daniel12mo ago

Query data is undefined for a bit and is then populated. How to use with React State?

I have an asychronous submit function that's called upon a button press. It refetches the query with the new values and then uses setProductResponse to set the values... if query.data is truthy, which is almost never is unless I spam the button. I know what the problem is and I've ran into this into the past, but I forgot what's the best way to deal with it. The query data is undefined for a short bit while the data is actually being fetched, so I need to set the state afterwards, but I'm not exactly sure how to do so. I thought .then would resolve it, but it didn't. Any help would be much appreciated! Here's my code:
const query = trpc.multiply.useQuery(
{
numberOne: Number(numberOne),
numberTwo: Number(numberTwo),
},
{ enabled: false }
);

// it's intially undefined, but later isn't. what's the best practice to handle this?
const submit = async () => {
query.refetch().then(() => {
console.log(query);
if (query.data) {
console.log("success!");
setProductResponse({
product: query.data.product,
isSuccess: query.isSuccess,
});
} else {
console.log("failure!");
}
});
};
const query = trpc.multiply.useQuery(
{
numberOne: Number(numberOne),
numberTwo: Number(numberTwo),
},
{ enabled: false }
);

// it's intially undefined, but later isn't. what's the best practice to handle this?
const submit = async () => {
query.refetch().then(() => {
console.log(query);
if (query.data) {
console.log("success!");
setProductResponse({
product: query.data.product,
isSuccess: query.isSuccess,
});
} else {
console.log("failure!");
}
});
};
3 Replies
the_riz
the_riz12mo ago
I don't know the answer to your question, sorry. But I'll note that you are using "async" without "await"-ing anything - you're changing into promise chaining. You might want to check for the query state and handing of it is loading, or is error, before immediately jumping to the setting of state.
mark salsbery
mark salsbery12mo ago
The hook is really designed to be used data driven…let the queries happen when input data changes, and use the returned state variables to drive the ui as they change. No need to manually refetch and no need to duplicate the returned data (state). I suppose if you must do it all manually then an onSuccess callback could be used on the query. But the callbacks are deprecated. That leaves a useEffect I guess, since technically when the query gets to the state you want it’s a side effect… Regardless, as you’ve seen you can’t just use query.data when the refetch promise resolves. At that point I’m pretty sure query is the same set of state variables returned by useQuery
Dani;
Dani;12mo ago
You should have access to the query data in your .then callback, of course you can also use async-await
query.refetch().then((x) => {
console.log(x.data);
})
query.refetch().then((x) => {
console.log(x.data);
})
Alternatively, you use the trpc client directly if you don't need this data to be cached by react-query:
function App() {
const trpcContext = trpc.useContext();

async function submit() {
try {
const data = await trpcContext.multiply.fetch({
numberOne: Number(numberOne),
numberTwo: Number(numberTwo)
});
} catch(error) {
// ...
}
}
}
function App() {
const trpcContext = trpc.useContext();

async function submit() {
try {
const data = await trpcContext.multiply.fetch({
numberOne: Number(numberOne),
numberTwo: Number(numberTwo)
});
} catch(error) {
// ...
}
}
}