我试图在一次成功后重新获取一些查询,但它不工作!
使用refetchQueries()
/invalidateQueries()
两种方法处理1- onSuccess回调
export const useMutateAcceptedOrder = () => {
const queryClient = useQueryClient();
return useMutation(
['AcceptedOrder'],
(bodyQuery: AcceptedOrderProps) => acceptOrder(bodyQuery),
{
onSuccess: () => {
console.log('success, refetch now!');
queryClient.invalidateQueries(['getNewOrders']); // not work
queryClient.refetchQueries(['getNewOrders']); // not work
},
onError: () => {
console.error('err');
queryClient.invalidateQueries(['getNewOrders']); // not work
},
},
);
};
第二种方式
const {mutateAsync: onAcceptOrder, isLoading} = useMutateAcceptedOrder();
const acceptOrder = async (orderId: string) => {
const body = {
device: 'iPhone',
version: '1.0.0',
location_lat: '10.10',
location_lng: '10.10',
orderId: orderId,
os: Platform.OS,
source: 'mobile',
token: userInfo.token,
};
await onAcceptOrder(body);
queryClient.refetchQueries(['getNewOrders']); // not work
queryClient.invalidateQueries(['getActiveOrders']); // not work
handleClosetModalPress();
};
成功后我想重新获取的查询示例
export const useNewOrders = (bodyQuery: {token: string | null}) => {
console.log('token>>', bodyQuery.token);
return useQuery(['getNewOrders'], () => getNewOrders(bodyQuery),
{
enabled: bodyQuery.token != null,
});
};
App.tsx
const App: React.FC<AppProps> = ({}) => {
const queryClient = new QueryClient();
if (__DEV__) {
import('react-query-native-devtools').then(({addPlugin}) => {
console.log('addPlugin');
addPlugin({queryClient});
});
}
useEffect(() => {
RNBootSplash.hide({fade: true}); // fade
}, []);
return (
<GestureHandlerRootView style={{flex: 1}}>
<QueryClientProvider client={queryClient}>
<BottomSheetModalProvider>
<AppContainer />
</BottomSheetModalProvider>
</QueryClientProvider>
</GestureHandlerRootView>
);
};
export default App;
,
编辑
所以在使用react-query-native-devtools
调试工具后,我看不到调试器中记录的第一个选项卡中的任何查询!虽然数据很好。
所以我猜这就是为什么refetch在这种情况下不起作用!
第一个选项卡中的任何查询都不能再次重新获取
复制步骤:
- 打开App - Active选项卡(第一个选项卡)
- 检查查询的状态
- 调试器中无记录
- 导航到任何其他屏幕/选项卡
- 查询状态
调试器中记录的所有屏幕查询
Per https://tkdodo.eu/blog/react-query-fa-qs#2-the-queryclient-is-not-stable:
如果你将客户端创建移动到App组件中,并且你的组件由于其他原因(例如路由更改)重新渲染,你的缓存将被丢弃:
需要像这样初始化queryClient
:
const [queryClient] = React.useState(() => new QueryClient())
我正面临着同样的问题,并没有能够找到一个适当的解决方案,但我已经找到了一个hack的工作方法。你只需调用你的refetch函数或在setTimeout中使查询无效。
这是一个比较老的问题,但我遇到了同样的问题。最后,我用几种方法解决了这个问题:
#1我改变了我的更新API端点,以便在修改记录后,它发送整个新记录回来,我最终做queryClient.setQueryData
来更新本地缓存。
#2尽管queryClient.invalidateQueries
是复数,我还是将每个查询键的失效都改为单数。
#3修改我的代码库,以确保只有一个new QueryClient
的实例,其他地方都使用useQueryClient
#4最后,也许是最不重要的,我把.then()
添加到invalidateQueries
,以防异步代码永远不会被执行。
注意https://tanstack.com/query/v4/docs/react/guides/query-invalidation#query-matching-with-invalidatequeries invalidate查询调用似乎只有在我添加了提到的fetchType
参数后才能工作。
下面是https://tanstack.com/query/v4/docs/react/reference/QueryClient#queryclientsetqueriesdata
的文档下面是我上面所做的一个完整的例子。
const _updateCharacter = useMutation<Character, Error, Character>({
mutationFn: (character: Character) => api.update_character(character),
onSuccess: (updated_character) => {
queryClient.setQueryData(
['book', activeBook.id, 'character', updated_character.id],
() => updated_character
)
queryClient
.invalidateQueries({
queryKey: ['book', activeBook.id, 'characters'],
exact: true,
refetchType: 'active'
})
.then()
},
onError: (error) => {
console.log(error)
}
})
这是一个详细的图书库存管理系统。目标是更新特定字符的详细信息,但除此之外,还要更新所有字符的列表以反映名称更改,注意字数计数和最后更新的字段。
不相关,但是每个字符记录都有一个内部id主键和一个暴露的snowflake
唯一标识符,所以这就是为什么我可以通过将记录传递给API而不需要其相关的书。
我希望这能帮助到其他人,让他们不要因为什么都不管用而慢慢失去理智。