Apollo-link-state writeQuery не обновляет ROOT_QUERY в кеше, предотвращая повторный рендеринг компонента

Я реализую OAuth с помощью специального провайдера. Итак, у меня есть компонент Auth, где внутри componentDidMount:

client.mutate({
  mutation: CURRENT_USER_MUTATION,
  variables: {
    token: (response.data.token.value) || null,
   },
});

Моя мутация выглядит так:

gql`
  mutation($token: String!) {
    CurrentUser(token: $token) @client
  }
`;

И у меня есть резольвер:

defaults: {
  current_user: null,
},
resolvers: {
  Mutation: {
    CurrentUser: (_: any, { token }: { token: string }, { cache }: { cache: Object }): null => {
    const { user } = decodeJWT(token);

    cache.writeQuery({
      query: CURRENT_USER,
      data: {
        current_user: {
          __typename: 'user',
          id: user.id,
          name: user.name,
          level: user.level,
          email: user.email,
        },
      },
    });

    return cache.readQuery({ query: CURRENT_USER });
  },
},

А потом что-то случилось, когда я смотрю внутрь отладчика chrome apollo, я ясно вижу это:

Apollo-link-state writeQuery не обновляет ROOT_QUERY в кеше, предотвращая повторный рендеринг компонента

Таким образом, данные уже находятся в кеше Apollo, но ROOT_QUERY все еще имеет значение NULL в качестве текущего пользователя.

Также, когда я пытаюсь использовать компонент react-apolloMutation следующим образом:

<Mutation mutation = {CURRENT_USER_MUTATION}>
  {(mutate: Function,): React.Node => {
    return (
      <button type = "button" onClick = {(): Function => mutate(({ variables: { token: '123' } }: Object))}>
        Do it
       </button>
     );
   }}
 </Mutation>

Тогда он отлично работает.

Таким образом, похоже, что после использования cache.writeQuery другой компонент / кеш не уведомляет о запущенной мутации.

Буду признателен за помощь :)

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
0
1 162
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Итак, в конце я обнаружил, что проблема была в другом месте: P Мой друг Михал предложил мне это, сделав рабочий пример моего кода здесь: https://codesandbox.io/s/l57k8v3o67

Итак, несколько выводов: 1. Компонент будет повторно извлекать / повторно отображать только при обнаружении взаимодействия с пользователем. Так, например, щелчок, поэтому компонент с кликабельной кнопкой работает или делается какой-то запрос к серверу.

  1. У Apollo есть несколько ошибок :) У меня есть другой компонент под названием <PrivateRoute />, в основном он проверяет, есть ли у нас current_user, а затем перенаправляет или отображает маршрут, вот он: https://gist.github.com/bslipek/b11caefba31599e30d498beaf8644cec И у этого компонента есть ошибка с проблемой от ere: https://github.com/apollographql/apollo-link-state/issues/236

Так что в основном, если вы визуализируете компонент с запросом в локальное состояние, и вы не устанавливаете fetchPolicy='cache-first', Apollo вернется к значениям по умолчанию.

Похоже, ваша мутация CurrentUser неправильная.

Это должно работать:

Mutation: {
  CurrentUser: (_: any, { token }: { token: string }, { cache }: { cache: Object 
}): null => {
  const { user } = decodeJWT(token);

  cache.writeQuery({
    query: CURRENT_USER,
    data: {
      current_user: {
        __typename: 'user',
        id: user.id,
        name: user.name,
        level: user.level,
        email: user.email,
      },
    },
  });

  return {
      current_user: {
        __typename: 'user',
        id: user.id,
        name: user.name,
        level: user.level,
        email: user.email,
      },
    }
},

Мутация в порядке, возможно, возврат cache.readQuery не очень хорош для производительности (?), Но работает нормально.

Bartek S 30.08.2018 13:54

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