2

I am trying to use useQuery for smart contract interaction.

The problem is, the contract return from useContract is null initially, as library and chainId are null initially.

So, the first fetch from useQuery is using a null contract to call the fetchPaginated function. Even library and chainId got initialised such that contract is not null, the useQuery does not get refetched.

The contract is a complex object that can't be set as query keys.

How to trigger the refetch for this kind of dynamic query function in useQuery?

Below are the codes:

// hook for handling contract
export function useContract<T extends Contract = Contract>(
  address: string,
  ABI: any,
  withSignerIfPossible = true,
): T | null {
  const { library, account, chainId } = useWeb3React();

  return useMemo(() => {
    if (!address || !ABI || !library || !chainId) return null;
    try {
      return getContract(
        address,
        ABI,
        library,
        withSignerIfPossible && account ? account : undefined,
      );
    } catch (error) {
      console.error('Failed to get contract', error);
      return null;
    }
  }, [address, ABI, library, chainId, withSignerIfPossible, account]) as T;
}

// The useQuery that want to get refetched
export const useFetchERC20Contracts = (
  page: number,
  pageSize: number,
) => {
  const contract = useContract();

  const result = useQuery<Response>(
    ['contract', page, pageSize],
    async () => {
      if (!contract) {
        return [];
      }
      return contract.fetchPaginated(page, pageSize);
    },
    { cacheTime: 0 },
  );

  return result;
};

1 Answer 1

0

everything that the queryFn depends on and that should drive the query to re-fetch should go into the query key. If you can't put contract there for some reason, you have to add its dependencies, in this case:

address, ABI, library, chainId, withSignerIfPossible, account

generally, I wouldn't separate this into two hooks. I would just have the queryFn call getContract directly, because that makes the dependencies obvious.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.