Как запустить graphql useQuery по требованию только один раз?

#vue.js #graphql #vue-component #apollo-client #vue-composition-api

#vue.js #graphql #vue-компонент #apollo-клиент #vue-состав-api

Вопрос:

С помощью graphql-codegenerator мы создали graphql, useQuery который корректно извлекает данные из серверной части. Когда строка вводится в поле ввода driverRule , вызывается функция для проверки ввода, которая, в свою очередь, должна вызывать useQuery только один раз.

Проблема

Однако, когда enable мы ref немедленно выполняем запрос с useQuery, с refetch() помощью метода вызывается второе выполнение. Все последующие вызовы driverRule будут вызывать useQuery только один раз по желанию. Но самый первый вызов делает это дважды, что нежелательно.

 import {computed, defineComponent, ref } from '@vue/composition-api'
import { useSapTruckRosterDriverQuery } from 'src/graphql/generated/operations'

export default defineComponent({
  setup(_, { emit }) {
    const showTruckId = ref(false)
    const driverId = computed(() => (!showTruckId.value ? answer.value : ''))
    const queryEnabled = ref<'driver' | 'truck'>()

    const { refetch: getDriverQuery } = useSapTruckRosterDriverQuery(
      () => ({ id: driverId.value }),
      () => ({ enabled: queryEnabled.value === 'driver' })
    )

    const driverRule = async (value: string) => {
      queryEnabled.value = 'driver'

      const result = await getDriverQuery({ id: value })

      if (result.data.driver.__typename === 'DriverArray') {
        return result.data.driver.data?.length ? true : 'Truck not found'
      }
    }
 

Что мы пробовали:

  • Перемещение useQuery внутри driverRule функции, но это приводит к следующей ошибке:

[Vue warn]: onServerPrefetch вызывается, когда нет активного экземпляра компонента, с которым нужно связать. API-интерфейсы внедрения жизненного цикла могут использоваться только во время выполнения setup() .

  • Используйте запрос с опцией emabled: false и только refetch() в driverRule . Это вообще не приводит к выполнению useQuery

Обходной путь

Примите поведение по умолчанию и включите запрос по умолчанию со значением статической переменной и используйте не результат первого запуска , а только результат из refetch() . Это все равно приводит к 2 вызовам серверной части, но этого нельзя избежать.

     const { refetch: getDriverQuery } = useSapTruckRosterDriverQuery(
      { id: 'initialQueryActivationCall' }
    )

    const driverRule = async (value: string) => {
      const result = await getDriverQuery({ id: value })
      if (result.data.driver.__typename === 'DriverArray') {
        return result.data.driver.data?.length ? true : 'Truck not found'
      }
    }
 

Вопрос

Кажется, действительно сложно просто вызвать useQuery только один раз, когда driverRule вызывается функция. Как мы можем избежать 2 вызовов, когда требуется только 1 вызов серверной части?

Комментарии:

1. Вы заглядывали в useLazyQuery ? Это позволяет вам указывать, когда должен быть запущен запрос.

Ответ №1:

Вы можете использовать useApolloClient из @vue / apollo-composable пакета.

 //other imports...
import { useApolloClient } from '@vue/apollo-composable'
import { gql } from '@apollo/client/core'

export default defineComponent({
    setup() {
        const { client } = useApolloClient()

        const GET_DOGS = gql`
            query GetDogs {
                dogs {
                   id
                   breed
                }
            }
        `;

        const getDogs = async (): Promise<void> => {
            const { data, } = await client.query({
                query: GET_DOGS
            })
        }

        return {
            getDogs,
        }
    },
})