admin管理员组文章数量:1287553
I am using "react-query" to call an API from a ponent . For the purpose of this question , I am returning a mock response from the API .
Every time , I open the dropdown , the useQuery function is called which in turn calls the mock API .
App.js
import React from 'react';
import './style.css';
import { QueryClient, QueryClientProvider } from 'react-query';
import { DropDown } from './Dropdown.js';
const queryClient = new QueryClient();
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<DropDown />
</div>
</QueryClientProvider>
);
}
Dropdown.js
import React from 'react';
import { useQuery } from 'react-query';
export const DropDown = () => {
console.log('DropDown re-rendered');
const { data, isLoading, isError } = useQuery('API', () => {
return new Promise((resolve, reject) => {
console.log('API called');
resolve(['mockData']);
});
});
return (
<>
<select>
<option> 1 </option>
<option> 2 </option>
</select>
</>
);
};
You can find the demo here :
In the console you will see that every time you open the dropdown , useQuery is called.
Stackblitz Editor url : /Dropdown.js
As an alternative to avoid this , I can use the traditional useEffect to make the API calls but I was looking at leveraging the caching advantage that useQuery provides but I am stuck due to this "re-rendering" issue .
Any suggestions / modifications ?
I am using "react-query" to call an API from a ponent . For the purpose of this question , I am returning a mock response from the API .
Every time , I open the dropdown , the useQuery function is called which in turn calls the mock API .
App.js
import React from 'react';
import './style.css';
import { QueryClient, QueryClientProvider } from 'react-query';
import { DropDown } from './Dropdown.js';
const queryClient = new QueryClient();
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<DropDown />
</div>
</QueryClientProvider>
);
}
Dropdown.js
import React from 'react';
import { useQuery } from 'react-query';
export const DropDown = () => {
console.log('DropDown re-rendered');
const { data, isLoading, isError } = useQuery('API', () => {
return new Promise((resolve, reject) => {
console.log('API called');
resolve(['mockData']);
});
});
return (
<>
<select>
<option> 1 </option>
<option> 2 </option>
</select>
</>
);
};
You can find the demo here : https://react-quxtxd.stackblitz.io
In the console you will see that every time you open the dropdown , useQuery is called.
Stackblitz Editor url : https://stackblitz./edit/react-quxtxd?file=src/Dropdown.js
As an alternative to avoid this , I can use the traditional useEffect to make the API calls but I was looking at leveraging the caching advantage that useQuery provides but I am stuck due to this "re-rendering" issue .
Any suggestions / modifications ?
Share Improve this question asked May 5, 2022 at 16:22 Ananth KumbleAnanth Kumble 1521 gold badge2 silver badges15 bronze badges 7- What is the purpose of the API call? You may want to consider moving the call to a parent ponent and passing in the data from the call as props to the dropdown ponent – gloo Commented May 5, 2022 at 16:36
- The purpose of the API call is to populate the dropdown . I have tried moving the api call to a parent ponent but even that results in re-rendering the parent . Basically in whichever ponent I move the API call to - that ponent re-renders every time the child ponent dropdown is opened – Ananth Kumble Commented May 5, 2022 at 16:38
- Have you seen this post stackoverflow./questions/67040687/… – gloo Commented May 5, 2022 at 16:48
- No I haven't but in the documentation it is mentioned about "refetchOnWindowFocus: false" . This is true by default. When I set this to false , the API is not called. – Ananth Kumble Commented May 5, 2022 at 17:02
-
You may also want to look at
staleTime
andcacheTime
: (stackoverflow./questions/71282427/…) – gloo Commented May 5, 2022 at 17:13
2 Answers
Reset to default 7This works for me
{ refetchOnWindowFocus: false }
Usage:
const { data, status } = useQuery("users", fetchUsers, {
refetchOnWindowFocus: false
});
If all your queries need this config. It's good to add this to defaultOptions
of your queryClient
// App.tsx
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
},
},
});
<QueryClientProvider client={queryClient}>
...
</QueryClientProvider>
It seems that the original stackblitz has been fixed, so the issue is no longer reproducible. For posterity:
You've probably seen a background refetch due to focusing the window. This is because staleTime
defaults to 0
and refetchOnWindowFocus
defaults to true
. You can either turn off the flag, or set a higher staleTime
(remended).
本文标签: javascriptReact useQuery called multiple times when dropdown is openedStack Overflow
版权声明:本文标题:javascript - React useQuery called multiple times when dropdown is opened - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741223008a2361326.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论