Skip to content

[Feature] Conditional Queries #361

@daveycodez

Description

@daveycodez

As of right now there is no way to have a query only run given certain conditions. I've created a custom useQuery wrapper that provides a solution in React, it would be great if the official useQuery hook in React could support this:

import type {
    Models,
    SchemaQuery,
    SubscriptionOptions,
    SubscriptionSignalPayload,
    TriplitClient
} from "@triplit/client"
import type { WorkerClient } from "@triplit/client/worker-client"
import { createStateSubscription } from "@triplit/react"
import { useCallback, useMemo, useState, useSyncExternalStore } from "react"

export function useConditionalQuery<M extends Models<M>, Q extends SchemaQuery<M>>(
    client: TriplitClient<M> | WorkerClient<M>,
    query?: Q | false | null | "" | 0,
    options?: Partial<SubscriptionOptions> & { disabled?: boolean }
) {
    const stringifiedQuery = !options?.disabled && query && JSON.stringify(query)
    const localOnly = !!options?.localOnly

    const defaultValue: SubscriptionSignalPayload<M, Q> = {
        results: undefined,
        fetching: true,
        fetchingLocal: false,
        fetchingRemote: false,
        error: undefined
    }

    // biome-ignore lint/correctness/useExhaustiveDependencies:
    const [subscribe, snapshot] = useMemo(
        () =>
            stringifiedQuery
                ? createStateSubscription(client, query, options)
                : [() => () => {}, () => defaultValue],
        [stringifiedQuery, localOnly]
    )

    const getServerSnapshot = useCallback(() => snapshot(), [snapshot])
    return useSyncExternalStore(subscribe, snapshot, getServerSnapshot)
}

This allows you to pass false-y values as query or to specify disabled in the options. It works like a charm, when the query is disabled it simply does nothing, doesn't even create the subscription. I'd love if the official useQuery hook had this implementation. This is how the SWR and TS Query DX is for handling conditional queries.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions