我使用useQuery钩子来获取数据,它在重新渲染期间被调用多次,但onSuccess回调只被调用一次。
export async function postWithoutCancellation({ queryKey, pageParam, responseType }) {
const url = queryKey[0];
let body = queryKey[1];
if (pageParam) {
body = { ...body, ...pageParam };
}
const { data } = await axiosInstance.post(url, body, {
...config1,
responseType,
});
return data;
}
const [lazyLoadRowDataQuery, setlazyLoadRowDataQuery] = useState(null);
const metricDataLazyLoad = useQuery(
[
`/api/call`,
{
...filters,
queries: getQueryMetrics(selectedDimensions, lazyLoadRowDataQuery),
// ...(view_metrics ? { attributionType: view_metrics } : {}),
},
],
postWithoutCancellation,
{
enabled: !!lazyLoadRowDataQuery,
onSuccess: (data) => {
console.log('On success callback', data, lazyLoadRowDataQuery)
}
}
);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
console.log('Entries', entries, timeouts.current)
entries.forEach(e => {
const rowKey = e?.target?.getAttribute('data-row-key') as string;
if (e.isIntersecting) {
const timerId = setTimeout(() => {
// observer.unobserve(e.target)
// handling
const element = paginatedData.find(item => item.key === +rowKey);
setlazyLoadRowDataQuery(element);
// metricDataLazyLoad.refetch();
// metricDataLazyLoad.mutation();
}, 1000) // delay for 1 second
timeouts.current[rowKey] = timerId
} else {
clearTimeout(timeouts.current[rowKey])
}
})
}, {
root: tableRef.current.querySelector('.ant-table-body'),
threshold: 0
}
);
const tableRows = tableRef.current.querySelectorAll('.ant-table-row');
// observer.observe(tableRows[0]);
console.log('Table rows', tableRows, tableRef.current.querySelector('.ant-table-tbody'));
if (Array.from(tableRows).length > 0) {
Array.from(tableRows).forEach((item: any) => observer.observe(item))
}
return () => {
if (Array.from(tableRows).length > 0) {
Array.from(tableRows).forEach((item: any) => observer.disconnect(item))
}
};
}, [paginatedData, timeouts]);
假设,如果视图中有5个元素,则回调将被调用5次,这将触发setlazyLoadRowDataQuery 5次,因此,进行了5次网络调用,但onSuccess回调只被调用一次,这是针对最后一个数据。对于初始的4次调用,回调永远不会执行。
我尝试使用useQueries钩子,但是状态维护有点复杂
您在useEffect钩子中多次设置lazyLoadRowDataQuery状态,从而触发useQuery钩子多次获取数据。因此,onSuccess回调只会在最后一次获取数据时调用。而不是settimeout,你使用debching技术延迟setlazyLoadRowDataQuery方法的执行,直到一定的时间已经过去,然后这将防止多个网络调用,并确保onSuccess回调只被调用一次