В чем разница между useQuery и useLazyQuery в Apollo GraphQL?

#reactjs #graphql #apollo

#reactjs #graphql #apollo

Вопрос:

Я просматривал документацию по перехватчикам Apollo React.

И увидел, что есть два перехватчика запросов, для которых нужно использовать useQuery и useLazyQuery

Я читал эту страницу. https://www.apollographql.com/docs/react/api/react/hooks /

Может кто-нибудь объяснить мне, в чем разница между ними и в каком случае это следует использовать.

Ответ №1:

Когда useQuery вызывается компонентом, он впоследствии запускает запрос.

Но когда useLazyQuery вызывается, он не запускает запрос впоследствии, а вместо этого возвращает функцию, которую можно использовать для запуска запроса вручную. Это объясняется на этой странице:https://www.apollographql.com/docs/react/data/queries/#manual-execution-with-uselazyquery

Когда React монтирует и отображает компонент, вызывающий useQuery перехват, клиент Apollo автоматически выполняет указанный запрос. Но что, если вы хотите выполнить запрос в ответ на другое событие, например, при нажатии пользователем кнопки? useLazyQuery Хук идеально подходит для выполнения запросов в ответ на события, отличные от рендеринга компонента. Этот хук действует точно так же, useQuery за одним ключевым исключением: при useLazyQuery вызове он не выполняет немедленно связанный с ним запрос. Вместо этого он возвращает функцию в своем результирующем кортеже, которую вы можете вызывать всякий раз, когда будете готовы выполнить запрос.

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

1. Я использовал «useLazyQuery» и отправлял переменные из состояния с запросом, и каждый раз, когда я изменяю состояние входных данных, запрос выполняется каждый раз при монтировании компонента, хотя я использовал его по событию onClick.

2. @Sharif в том, как вы его используете, должна быть ошибка (например, непреднамеренное выполнение функции запроса), иначе вы можете сообщить о проблеме github.com/apollographql/apollo-client/issues поскольку это не так, основываясь на их документации

3. вы можете создать новый вопрос и предоставить здесь, чтобы я мог взглянуть? также высоко ценится минимально воспроизводимая среда, такая как codesandbox.

Ответ №2:

Предположим, у вас есть компонент, в котором вы вызываете useQuery, затем, как только компонент монтируется, запускается useQuery и данные извлекаются с сервера. Но если вы используете useLazyQuery в этом компоненте вместо useQuery, запрос не выполняется, и данные не извлекаются при подключении компонента. Вместо этого вы можете запустить запрос на основе вашего требования, скажем, после нажатия кнопки. Пример:

 import React, { useState } from 'react';
import { useLazyQuery } from '@apollo/client';

function DelayedQuery() {
  const [dog, setDog] = useState(null);
  const [getDog, { loading, data }] = useLazyQuery(GET_DOG_PHOTO);

  if (loading) return <p>Loading ...</p>;

  if (data amp;amp; data.dog) {
    setDog(data.dog);
  }

  return (
    <div>
      {dog amp;amp; <img src={dog.displayImage} />}
      <button onClick={() => getDog({ variables: { breed: 'bulldog' } })}>
        Click me!
      </button>
    </div>
  );
}
  

Здесь, как только вы нажимаете кнопку, выполняется только запрос, извлекаются данные и отображается изображение. Но если бы вы использовали useQuery вместо этого, перед нажатием кнопки (т. Е. Когда компонент монтируется), данные были бы извлечены и изображение было бы отображено

Ответ №3:

Обновить:

https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md#improvements-due-to-brainkim-in-8875

useLazyQuery теперь возвращает обещание, начиная с Apollo Client 3.5.0 (2021-11-08)

Ответ №4:

Что-то, о чем, кажется, не говорится, но я просто понимаю, что useLazyQuery не считывается из кэша. Это несколько похоже на вызов refetch функции, возвращаемой из useQuery .

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

1. Да, я около 3 часов пытался выяснить, почему мой запрос всегда извлекается из API даже с cache-first правилом. Я ничего не видел в документах, говорящих об этом