是否可以在使用 React Query 更新缓存后重新渲染组件?
Is it possible to re-render a component after updating cache with React Query?
在根组件中,我从缓存中收到了这个数据。
const queryClient = useQueryClient();
const data = queryClient.getQueryData('prototypes');
在另一个组件中,在触发一个函数后,我更改了缓存中的数据(使用乐观更新)。
尽管缓存中的数据已更改并显示在 Devtools 中,但根组件中的新数据未显示且组件未刷新。
如何在更改缓存后重新渲染组件?
之前我在Nextjs中使用这种方式以Ssr方式获取数据
export const getServerSideProps = wrapper.getServerSideProps(
(store) =>
async ({ req }) => {
const queryClient = new QueryClient();
await queryClient.prefetchQuery('prototypes', getPrototypes);
return {
props: { dehydratedState: dehydrate(queryClient) },
};
}
);
在一个子组件中,我使用 useQuery hook 来获取数据。
const { data: prototypes }: { data: FilterPrototypesByDateQuery } = useQuery(
'prototypes',
getPrototypes
);
虽然数据存在于缓存中,但在安装此组件时,我在网络中看到触发了获取原型的新请求。
在其他子组件中,当我喜欢一个原型时,我使用乐观更新来更新缓存。但是我看到一个新的原型请求又被触发了。
const { mutate: likePrototype } = useLikePrototypeMutation({
onMutate: async (like) => {
const previousPrototype: FilterPrototypesByDateQuery =
queryClient.getQueryData('prototypes');
const newState = produce(previousPrototype, (draft) => {
const index = draft.prototype_getPrototypes.result.items.findIndex(
(item) => item.id === prototypeId
);
if (index > -1) {
draft.prototype_getPrototypes.result.items[index].isLiked = true;
}
});
queryClient.setQueryData('prototypes', newState);
return { previousPrototype };
},
onSettled: () => {
queryClient.invalidateQueries('prototypes');
},
});
如果您希望查询不再获取新数据,第一步是将其缓存和过时时间设置为无穷大。这使得 RQ 永远记住数据,但也总是 return 来自缓存。
const { data: prototypes } = useQuery('prototypes', getPrototypes, {
cacheTime: Infinity,
staleTime: Infinity,
});
下一步是您不应该手动使查询无效。当您使用 setQueryData
更改它时,它将被更新。
const { mutate: likePrototype } = useLikePrototypeMutation({
onMutate: async (like) => {
// ...
// this causes the component using that query to update
queryClient.setQueryData('prototypes', newState);
// ...
},
// no onSettled here
// just rollback in onError
});
在根组件中,我从缓存中收到了这个数据。
const queryClient = useQueryClient();
const data = queryClient.getQueryData('prototypes');
在另一个组件中,在触发一个函数后,我更改了缓存中的数据(使用乐观更新)。 尽管缓存中的数据已更改并显示在 Devtools 中,但根组件中的新数据未显示且组件未刷新。
如何在更改缓存后重新渲染组件?
之前我在Nextjs中使用这种方式以Ssr方式获取数据
export const getServerSideProps = wrapper.getServerSideProps(
(store) =>
async ({ req }) => {
const queryClient = new QueryClient();
await queryClient.prefetchQuery('prototypes', getPrototypes);
return {
props: { dehydratedState: dehydrate(queryClient) },
};
}
);
在一个子组件中,我使用 useQuery hook 来获取数据。
const { data: prototypes }: { data: FilterPrototypesByDateQuery } = useQuery(
'prototypes',
getPrototypes
);
虽然数据存在于缓存中,但在安装此组件时,我在网络中看到触发了获取原型的新请求。
在其他子组件中,当我喜欢一个原型时,我使用乐观更新来更新缓存。但是我看到一个新的原型请求又被触发了。
const { mutate: likePrototype } = useLikePrototypeMutation({
onMutate: async (like) => {
const previousPrototype: FilterPrototypesByDateQuery =
queryClient.getQueryData('prototypes');
const newState = produce(previousPrototype, (draft) => {
const index = draft.prototype_getPrototypes.result.items.findIndex(
(item) => item.id === prototypeId
);
if (index > -1) {
draft.prototype_getPrototypes.result.items[index].isLiked = true;
}
});
queryClient.setQueryData('prototypes', newState);
return { previousPrototype };
},
onSettled: () => {
queryClient.invalidateQueries('prototypes');
},
});
如果您希望查询不再获取新数据,第一步是将其缓存和过时时间设置为无穷大。这使得 RQ 永远记住数据,但也总是 return 来自缓存。
const { data: prototypes } = useQuery('prototypes', getPrototypes, {
cacheTime: Infinity,
staleTime: Infinity,
});
下一步是您不应该手动使查询无效。当您使用 setQueryData
更改它时,它将被更新。
const { mutate: likePrototype } = useLikePrototypeMutation({
onMutate: async (like) => {
// ...
// this causes the component using that query to update
queryClient.setQueryData('prototypes', newState);
// ...
},
// no onSettled here
// just rollback in onError
});