重新抓取查询不工作- React查询



我试图在一次成功后重新获取一些查询,但它不工作!

使用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而不需要其相关的书。

我希望这能帮助到其他人,让他们不要因为什么都不管用而慢慢失去理智。

最新更新