为什么 queryClient.setQueryData 在此示例中使用 react-query 花费这么长时间?
Why is queryClient.setQueryData taking so long in this example with react-query?
我正在使用 useQuery 和 setQueryData 使用 react-query 更新缓存,问题是 setQueryData 最多可能需要 2 分钟来更新数据,这可能是由于某种循环。我将每个页面映射到 'Styles' 数据,并使用响应中的数据更新与 pageIndex 匹配的页面上的样式、组和范围。我不知道为什么更新很长,我在这里使用 react-query 错了吗?顺便说一句,正在更新的数据一点也不大。
提前致谢。
export const useStyle = (styleId, pageIndex) => {
const queryClient = useQueryClient();
const { refetch } = useQuery('Style', () => fetchStyle(styleId), {
staleTime: Infinity,
refetchOnWindowFocus: false,
initialData: {},
onSuccess: (res) => {
queryClient.setQueryData('Styles', (oldData) => ({
pages: map(oldData.pages, (page, index) => ({
...page,
...(index === pageIndex
? {
Styles: {
...page.Styles,
...res.Styles,
},
Groups: {
...page.Groups,
...res.Groups,
},
Ranges: {
...page.Ranges,
...res.Ranges,
},
}
: {}),
})),
pagesParams: oldData.pageParams,
}));
},
});
return { refetchStyle: refetch };
};
我认为你在这里创建了一个无限循环:
useQuery('Styles')
订阅键 Styles
,因此只要该键下缓存中的某些内容发生变化,此组件将始终更新/重新呈现
- 在此查询的
onSuccess
中,您更新了同一个键 (Styles
)
- 此更新会通知所有观察者,因为他们应该知道这一变化
- 调用
setQueryData
也 触发 onSuccess
,因为 setQueryData
的处理方式与数据来自后端相同queryFn.
- 这将再次触发您的
onSuccess
,依此类推...
更好的问题是:你想解决什么问题?从表面上看,您希望在每次提取后执行一些数据转换。为此,您有多种选择,我已在此处详细概述了所有这些选择:https://tkdodo.eu/blog/react-query-data-transformations
但通常情况下,没有必要像那样合并数据。缓存最好是您从服务器获得的响应的 1:1 映射。
我已经通过使用 useMutation 而不是 useQuery 和 setQueryData 解决了这个问题,如果 onSuccess 循环是由 setQueryData 引起的,这是更好的方法。
我正在使用 useQuery 和 setQueryData 使用 react-query 更新缓存,问题是 setQueryData 最多可能需要 2 分钟来更新数据,这可能是由于某种循环。我将每个页面映射到 'Styles' 数据,并使用响应中的数据更新与 pageIndex 匹配的页面上的样式、组和范围。我不知道为什么更新很长,我在这里使用 react-query 错了吗?顺便说一句,正在更新的数据一点也不大。
提前致谢。
export const useStyle = (styleId, pageIndex) => {
const queryClient = useQueryClient();
const { refetch } = useQuery('Style', () => fetchStyle(styleId), {
staleTime: Infinity,
refetchOnWindowFocus: false,
initialData: {},
onSuccess: (res) => {
queryClient.setQueryData('Styles', (oldData) => ({
pages: map(oldData.pages, (page, index) => ({
...page,
...(index === pageIndex
? {
Styles: {
...page.Styles,
...res.Styles,
},
Groups: {
...page.Groups,
...res.Groups,
},
Ranges: {
...page.Ranges,
...res.Ranges,
},
}
: {}),
})),
pagesParams: oldData.pageParams,
}));
},
});
return { refetchStyle: refetch };
};
我认为你在这里创建了一个无限循环:
useQuery('Styles')
订阅键Styles
,因此只要该键下缓存中的某些内容发生变化,此组件将始终更新/重新呈现- 在此查询的
onSuccess
中,您更新了同一个键 (Styles
) - 此更新会通知所有观察者,因为他们应该知道这一变化
- 调用
setQueryData
也 触发onSuccess
,因为setQueryData
的处理方式与数据来自后端相同queryFn. - 这将再次触发您的
onSuccess
,依此类推...
更好的问题是:你想解决什么问题?从表面上看,您希望在每次提取后执行一些数据转换。为此,您有多种选择,我已在此处详细概述了所有这些选择:https://tkdodo.eu/blog/react-query-data-transformations
但通常情况下,没有必要像那样合并数据。缓存最好是您从服务器获得的响应的 1:1 映射。
我已经通过使用 useMutation 而不是 useQuery 和 setQueryData 解决了这个问题,如果 onSuccess 循环是由 setQueryData 引起的,这是更好的方法。