useQuery не возвращает обновленные данные

#reactjs #graphql #apollo

#reactjs #graphql #apollo

Вопрос:

  • у меня есть домашняя страница ( /home ) со списком продуктов в виде карточек (извлекаемых через useQuery ), каждая из которых имеет кнопку upvote
  • когда я нажимаю upvote, я запускаю мутацию для upvote изменение пользовательского интерфейса для обновления подсчета голосов
  • когда я перехожу на другую страницу, а затем возвращаюсь /home , useQuery не извлекает продукты с правильным подсчетом голосов
  • однако, когда я проверяю свою базу данных, все продукты имеют правильный подсчет голосов.

Почему useQuery не возвращает нужное количество, пока я не обновлю другую страницу?

для справки, вот это ниже:

 const Home = props => {
  const {data, loading, error} = useQuery(GET_PRODUCTS_LOGGED_IN, {
    variables: {
      userid: props.userid
    }
  });
  
  console.log(
    'data', data.products // this data is outdated after I go from /home -> /profile -> /home
  );

  return (
    <Container>
      {_.map(data.products, product => (
        <VoteButton
          hasVoted={product.hasVoted}
          likes={product.likes}
          productid={product.productid}
        />
      ))}
    </Container>
  );
}
  
 const VoteButton = ({likes, hasVoted, productid}) => {
  const [localHasVoted, updateLocalHasVoted] = useState(hasVoted);
  const [likesCount, updateLikesCount] = useState(likes);
  const [onVote] = useMutation(VOTE_PRODUCT);

  const onClickUpvote = (event) => {
    onVote({
      variables: {
        productid
      }
    })
    updateLocalHasVoted(!localHasVoted);
    updateLikesCount(localHasVoted ? likesCount - 1 : likesCount   1);
  }
  
  return (
    <VoteContainer onClick={onClickUpvote}>
        <VoteCount >{likesCount}</VoteCount>
    </VoteContainer>
  );
};
  

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

1. Вероятно, вы используете кеш в своем клиенте apollo, вам нужно обновить его вручную, это довольно раздражает: apollographql.com/docs/react/data/mutations /…

2. ах, чувак, я ненавижу это

3. используйте политику «только для сети», если вы не хотите «бороться» с [«раздражающими»] обновлениями кэша

Ответ №1:

При вызове useQuery вы можете фактически передать ему параметр конфигурации с именем ‘fetch-policy’, который сообщает Apollo, как вы хотите, чтобы запрос выполнялся между выполнением вызова или использованием кэша. Вы можете найти более подробную информацию здесь, параметры политики выборки Apollo. Быстрым решением было бы установить политику выборки для кеширования и сети, как в примере ниже.

   const {data, loading, error} = useQuery(GET_PRODUCTS_LOGGED_IN, {
    variables: {
      userid: props.userid
    },
    fetchPolicy: 'cache-and-network',
  });
  

Вы также можете сделать так, чтобы при возникновении вашей мутации он снова выполнял ваш запрос, установив опцию ‘refetch-queries’ при useMutation, как в приведенном ниже коде.
Это приведет к запуску вашего запроса сразу после того, как произойдет мутация.
Подробнее об этом можно прочитать здесь Параметры мутации Apollo

 const [onVote] = useMutation(VOTE_PRODUCT, {
  refetchQueries: [ {query: GET_PRODUCTS_LOGGED_IN } ],
});
  

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

1. да, я закончил использовать cache-and-network , спасибо за ответ, хотя