如何在wagmi@1.x中重新获取查询?invalidateQueries失效问题
解决wagmi@1.x中useContractRead的invalidateQueries无效问题
wagmi@1.x底层基于react-query,但useContractRead的查询键(queryKey)是内部自动生成的,并非直接使用函数名或scopeKey,所以直接用['balanceOf']作为queryKey无法匹配目标查询。以下是三种有效解决方案:
方案1:直接复用useContractRead返回的queryKey
useContractRead会返回当前查询的queryKey,你可以通过上下文或props将这个key传递到需要触发刷新的组件:
1. 在余额组件中暴露queryKey
// BalanceComponent.jsx import { useContractRead } from 'wagmi'; import { createContext, useContext } from 'react'; // 创建上下文用于传递queryKey const BalanceQueryKeyContext = createContext(null); export const useBalanceQueryKey = () => useContext(BalanceQueryKeyContext); export function BalanceComponent() { const balance = useContractRead({ address: '0x你的合约地址', abi: random.abi, functionName: 'balanceOf', args: ['0x用户地址'], // 如果balanceOf需要参数,必须和这里保持一致 onSuccess: () => { console.log('balanceOf refetched'); }, cacheTime: 0, staleTime: 0, }); return ( <BalanceQueryKeyContext.Provider value={balance.queryKey}> <div>当前余额:{balance.data?.toString()}</div> </BalanceQueryKeyContext.Provider> ); }
2. 在刷新按钮组件中使用该queryKey
// App.jsx import { useQueryClient } from 'wagmi'; import { useBalanceQueryKey } from './BalanceComponent'; function App() { const queryClient = useQueryClient(); const balanceQueryKey = useBalanceQueryKey(); return ( <button onClick={() => { if (balanceQueryKey) { queryClient.invalidateQueries({ queryKey: balanceQueryKey }); } }} > 刷新余额 </button> ); } export default App;
方案2:手动构造匹配的queryKey
wagmi@1.x中useContractRead的queryKey固定结构为:['wagmi', 'contractRead', { address, abi, functionName, args, chainId, ...其他配置 }],你需要严格匹配这些参数来构造queryKey:
// App.jsx import { useQueryClient } from 'wagmi'; import random from './abi文件路径'; // 导入你的ABI function App() { const queryClient = useQueryClient(); return ( <button onClick={() => { queryClient.invalidateQueries({ queryKey: [ 'wagmi', 'contractRead', { address: '0x你的合约地址', abi: random.abi, functionName: 'balanceOf', args: ['0x用户地址'], // 和useContractRead中的参数完全一致 // 如果指定了chainId,需要添加对应的chainId // chainId: 1, }, ], }); }} > 刷新余额 </button> ); } export default App;
方案3:批量匹配同类型查询
如果需要刷新所有functionName为balanceOf的合约读取查询,可以使用断言函数过滤:
queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'wagmi' && query.queryKey[1] === 'contractRead' && query.queryKey[2].functionName === 'balanceOf' });
内容的提问来源于stack exchange,提问作者yourcasualdev
相关产品推荐
相关产品推荐

