Как правильно связать useQuery и useMutation в GraphQL?

У меня есть useQuery и useMutation из react-apollo-hooks подряд. Я хочу иметь возможность использовать возвращаемые значения из useQuery в качестве переменных для useMutation. В настоящее время значения из useQuery не возвращаются вовремя для переменных, что приводит к тому, что переменные не определены.

const { data, error, loading } = useQuery(GET_POSTS, { 
    variables: {
        id: props.match.params.id
    }
})
const item = props.match.params.id
const owner = data.posts[0].author.id
const variables = { item , owner, startDate, endDate }
const bookItem = useMutation(CREATE_BOOKING_MUTATION, variables)

Переменная data.posts[0].author.id показывает undefined. Как убедиться, что возвращаемое значение определено вовремя?

Если вы можете запросить эти данные из серверной части, разве у вас уже нет этих данных для использования в распознавателе для мутации?

dijonkitchen 26.08.2021 23:14
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
1
5 205
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

How do I make sure that the returned value is defined in time?

Вы можете просто проверить условие после блока useQuery


ОБНОВИТЬ

Хуки нельзя называть условно.

Обычный совет - поместить условие в useEffect:

const { data, error, loading } = useQuery(GET_POSTS, { 
  variables: {
    id: props.match.params.id
  }
})
const item = props.match.params.id

// data.posts can be undefined at start
const owner = loading ? null : data.posts[0].author.id
const variables = { item , owner, startDate, endDate }
const bookItem = useMutation(CREATE_BOOKING_MUTATION, variables)
useEffect(() => {
  if (!loading) {
    bookItem(); // called when data ready
  }
})

Другой вариант: useApolloClient:

  • useQuery для загрузки данных, необходимых для мутации

  • const client = useApolloClient();

  • useEffect - условно (!loading или data не пусто) использовать client.mutate() с извлеченными (в запросе) данными в качестве переменных;

Пользовательский хук можно сделать с 3 параметрами: (query, mutation, { mapDataToVariables })

единственная проблема заключается в том, что если бы я размещал хуки после оператора if, я получаю сообщения об ошибках, такие как «React Hook «useMutation» вызывается условно. React Hooks должны вызываться в одном и том же порядке в каждом рендеринге компонента».

Kevvv 19.05.2019 14:56

Я думаю, вы можете передавать переменные, когда вы фактически вызываете мутацию, например:

...
const bookItem = useMutation(CREATE_BOOKING_MUTATION)
...
if (!loading && !error && data) {
  bookItem({
    variables: {
      owner: data.posts[0].author.id,
      ...
    }
  })
}

Другие вопросы по теме