我有一个母版页,它是一个项目列表,还有一个详细页,我可以在其中获取和更新项目。我有以下基于react-query库的钩子:
const useItems = (options) => useQuery(["item"], api.fetchItems(options)); // used by master page
const useItem = id => useQuery(["item", id], () => api.fetchItem(id)); // used by details page
const useUpdateItem = () => {
const queryClient = useQueryClient();
return useMutation(item => api.updateItem(item), {
onSuccess: ({id}) => {
queryClient.invalidateQueries(["item"]);
queryClient.invalidateQueries(["item", id]);
}
});
};UpdatePage组件有一个表单组件,它接受一个defaultValue并将其加载到它的本地“草稿”状态中-所以在这方面它是某种“不受控制的”,我不提升草稿状态。
// UpdatePage
const query = useItem(id);
const mutation = useUpdateItem();
return (
{query.isSuccess &&
!query.isLoading &&
<ItemForm defaultValue={query.data} onSubmit={mutation.mutate} />
}
);问题是在我更新后,转到母版页,然后返回到详细页,"defaultValue“在查询完成之前获取旧项目。我确实看到它冲击了网络中的API,新的价值又回来了,但为时已晚。如何在重新查询数据后才显示ItemForm?或者有更好的模式?
发布于 2021-02-24 22:39:55
我的updateItem应用编程接口函数从服务器返回单个更新的项。
我使用setQueryData解决了这个问题。
const useUpdateItem = () => {
const queryClient = useQueryClient();
// Note - api.updateItem is return the single updated item from the server
return useMutation(item => api.updateItem(item), {
onSuccess: data => {
const { id } = data;
// set the single item query
queryClient.setQueryData('item', id], data);
// set the item, in the all items query
queryClient.setQueryData(
['item'],
// loop through old. if this item replace, otherwise, don't
old => {
return old && old.map(d => (d.id === id ? data : d));
}
);
}
});
};我会说,react-query对键是挑剔的,即使它是模糊的。最初我的id是来自url搜索参数和一个字符串,但是从数据库返回的项是一个int,所以它不匹配。所以这里有个小问题。
此外,当我返回到Master列表页面时,我看到项目发生了变化,这对我来说是一种奇怪的来自redux的变化。我本以为在触发同步setQueryData时它就已经更改了。因为我使用的是react-router,所以“页面”是完全重新挂载的,所以我不确定为什么它要加载旧的查询数据,然后更改它。
发布于 2021-02-24 14:45:29
仅当查询处于无数据的硬加载状态时,isLoading才为true。否则,它将在进行后台重新获取时为您提供过时的数据。这在大多数情况下都是有意义的(在重新验证时使用stale)。在详细信息视图卸载后,您的数据会在缓存中保留5分钟,因为这是默认的cacheTime。
最简单的修复方法是将其设置为0,这样您就不会保留该数据。
您也可以对isFetching标志做出反应,但当请求发出时,此标志将始终为真,例如,对于窗口焦点重新获取也是如此。
旁注:默认情况下,invalidateQueries是模糊的,因此这将使列表和详细视图无效:queryClient.invalidateQueries(["item"])
https://stackoverflow.com/questions/66342553
复制相似问题