TanStackT
TanStack2y ago
1 reply
inner-olive

How to use `useSuspenseQuery` to ensure data is always there?

Hey all. I'm working on an app where basically each screen is bound to be accessed if the user is in an account. I want to develop a hook that will provide the account data and avoid doing undefined checks. Right now, I grad the account id from the url, pass it to a query where and use enabled to decide if the query should be called. It is called each time but the undefined checks are annoying. Another approach is to retun null early if (!accountId), which is also annoying.

Here is what I have so far:
import { useSearchParams } from 'react-router-dom';

import type { IAccount } from '@payhawk/public-api-contracts';

import {
    useGetAccountSuspense,
    useGetUserAccounts,
} from '@data';

export const useAccount = (): { account: IAccount; accountId: string } => {
    const [params, setParam] = useSearchParams();

    const accountId = params.get('account') ?? undefined;

    const userAccounts = useGetUserAccounts();
    const account = useGetAccountSuspense(accountId);

    // if no account id in path, navigate to the first account from all possible accounts
    if (!accountId && !account.isLoading && !account) {
        const firstAccount = userAccounts.data?.[0];

        if (firstAccount) {
            setParam(current => {
                current.set('account', firstAccount.id);
                return current;
            });
        }
    }

    return { account: account.data };
};

export const useGetAccountSuspense = (accountId?: string) => {
    return useSuspenseQuery({
        queryKey: ['accounts', accountId],
        queryFn: () => fetch(`/accounts/${accountId ?? ''}`);
    });
};


The thing is, params.get('account') might not be defined, in which case I want to redirect the user to one of their accounts.

My problem is that useSuspenseQuery does not allow for enabled and I have to do accountId ?? '' which causes an extra call to be made. I feel like this is a common issue, just not sure how to get around it.

Thanks!
Was this page helpful?