Apollo useQuery() - "refetch" игнорируется, если ответ такой же

Я пытаюсь использовать Apollo-client, чтобы получить информацию о моих пользователях, и столкнулся с этой проблемой:

у меня есть это Containerкомпонент, отвечающий за получение данных пользователя (не аутентификацию) после их визуализации. Пользователь может войти в систему или нет, запрос возвращает либоviewer = null или viewer = {...usersProps}.

Контейнер делает запрос const { data, refetch } = useQuery<Viewer>(VIEWER);, успешно получает ответ и сохраняет его в data свойство, которое я использую, чтобы читать .viewer from и установить его как моего текущего пользователя.

Затем пользователь может выйти из системы, как только они это сделают, я очищаю Containerсвойство пользователя setUser(undefined) (не показано в приведенном ниже коде, не важно).

Проблема возникла, когда я пытаюсь повторно войти в систему: Call of refetch вызывает graphql http-запрос, но поскольку он возвращает те же данные, которые были возвращены во время предыдущего первоначального входа в систему - useQuery() игнорирует и не обновляет data. Ну технически обновления быть не могло, данные те же. Итак, мой кодsetUser(viewer); не запускается во второй раз, и пользователь застревает на странице входа.

  const { data, refetch } = useQuery<Viewer>(VIEWER);

  const viewer = data && data.viewer;

  useEffect(() => {
    if (viewer) {
      setUser(viewer);
    }

  }, [ viewer ]);

Этот запрос с таким же игнорированием ответа почти имеет смысл, поэтому я попробовал другой подход с обратными вызовами:

  const { refetch } = useQuery<Viewer>(VIEWER, {
    onCompleted: data => {
      if (data.viewer) {
        setUser(data.viewer);
      }
    }
  });

Здесь я полностью ожидал, что Аполлон назовет onCompletedобратный вызов, с теми же данными или нет... но он этого не делает. Так что я как бы застрял в этом - как заставить Apollo реагировать на мой запрос?refetch чтобы я мог заново заселить user в моем Containerсостояние?

1 ответ

Это сценарий, в котором тайники Аполлона пригодятся. Клиент

import { resolvers, typeDefs } from './resolvers';

let cache = new InMemoryCache()
const client = new ApolloClient({
  cache,
  link: new HttpLink({
    uri: 'http://localhost:4000/graphql',
    headers: {
      authorization: localStorage.getItem('token'),
    },
  }),
  typeDefs,
  resolvers,
});

cache.writeData({
  data: {
    isLoggedIn: !!localStorage.getItem('token'),
    cartItems: [],
  },
})

Страница авторизации

const IS_LOGGED_IN = gql`
  query IsUserLoggedIn {
    isLoggedIn @client
  }
`;

function IsLoggedIn() {
  const { data } = useQuery(IS_LOGGED_IN);
  return data.isLoggedIn ? <Pages /> : <Login />;
}

onLogin

function Login() {
  const { data, refetch } = useQuery(LOGIN_QUERY);
  let viewer = data && data.viewer
  if (viewer){
    localStorage.setItem('token',viewer.token)
  }
  // rest of the stuff
}

onLogout

onLogout={() => {
        client.writeData({ data: { isLoggedIn: false } });
        localStorage.clear();
      }}

Для получения дополнительной информации об управлении местным государством. Проверьте это.

Надеюсь это поможет!

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