I have a three-check box type,
When I check any box I call refetch()
in useEffect()
.
The first time, I check all boxes and that returns the expected data!
but for some cases "rechange the checkboxes randomly", the returned data from API is "undefined" although it returns the expected data in Postman!
So I Guess should I need to provide a unique queryKey
for every data that I want to fetch
so I provide a random value "Date.now()" but still return undefined
Code snippet
type bodyQuery = {
product_id: number;
values: {};
};
const [fetch, setFetch] = useState<number>();
const [bodyQuery, setBodyQuery] = useState<bodyQuery>({
product_id: item.id,
values: {},
});
const {
data: updatedPrice,
status,
isFetching: loadingPrice,
refetch,
} = useQuery(
['getUpdatedPrice', fetch, bodyQuery],
() => getOptionsPrice(bodyQuery),
{
enabled: false,
},
);
console.log('@bodyQuery: ', bodyQuery);
console.log('@status: ', status);
console.log('@updatedPrice: ', updatedPrice);
useEffect(() => {
if (Object.keys(bodyQuery.values).length > 0) {
refetch();
}
}, [bodyQuery, refetch]);
export const getOptionsPrice = async (body: object) => {
try {
let response = await API.post('/filter/product/price', body);
return response.data?.detail?.price;
} catch (error) {
throw new Error(error);
}
};
I have a three-check box type,
When I check any box I call refetch()
in useEffect()
.
The first time, I check all boxes and that returns the expected data!
but for some cases "rechange the checkboxes randomly", the returned data from API is "undefined" although it returns the expected data in Postman!
So I Guess should I need to provide a unique queryKey
for every data that I want to fetch
so I provide a random value "Date.now()" but still return undefined
Code snippet
type bodyQuery = {
product_id: number;
values: {};
};
const [fetch, setFetch] = useState<number>();
const [bodyQuery, setBodyQuery] = useState<bodyQuery>({
product_id: item.id,
values: {},
});
const {
data: updatedPrice,
status,
isFetching: loadingPrice,
refetch,
} = useQuery(
['getUpdatedPrice', fetch, bodyQuery],
() => getOptionsPrice(bodyQuery),
{
enabled: false,
},
);
console.log('@bodyQuery: ', bodyQuery);
console.log('@status: ', status);
console.log('@updatedPrice: ', updatedPrice);
useEffect(() => {
if (Object.keys(bodyQuery.values).length > 0) {
refetch();
}
}, [bodyQuery, refetch]);
export const getOptionsPrice = async (body: object) => {
try {
let response = await API.post('/filter/product/price', body);
return response.data?.detail?.price;
} catch (error) {
throw new Error(error);
}
};
Share
Improve this question
asked Mar 27, 2021 at 15:12
Oliver DOliver D
2,8999 gold badges48 silver badges91 bronze badges
7
- Why do you call refetch in the useEffect? What happens if you click on an item? – Domino987 Commented Mar 27, 2021 at 15:22
-
@Domino987 I call refetch just if the bodyQuery changed because without calling it in useEffect the data not fetched
status: Idle
– Oliver D Commented Mar 27, 2021 at 15:28 - 1 So if you remove the enabled: false, it will be fetched on render, if is stale or not fetched yet. and use this as key: ['getUpdatedPrice', item.id] – Domino987 Commented Mar 27, 2021 at 15:29
- @Domino987 after doing what u said, the first time the query fetched once But when I click on any item 'checkbox' the data not fetched anymore – Oliver D Commented Mar 27, 2021 at 15:39
- Yes you need to invaldiate it on click, so call refetch on click of the item or queryClient.invalidateQueries(['getUpdatedPrice', item.id]) to get the new data. – Domino987 Commented Mar 27, 2021 at 15:41
1 Answer
Reset to default 7So after some elaboration in the chat, this problem can be solved by leveraging the useQuery key array.
Since it behaves like the dependency array in the useEffect
for example, everything that defines the resulted data should be inserted into it. Instead of triggering refetch
to update the data.
Here the key could look like this: ['getUpdatedPrice', item.id, ...Object.keys(bodyQuery.values)], which will trigger a new fetch if those values change and on initial render.