Apollo useQuery () - «refetch» ​​игнорируется, если ответ тот же - PullRequest
0 голосов
/ 22 сентября 2019

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

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

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

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

Проблема возникла при попытке повторного входа в систему: вызов refetch инициирует http-запрос graphql, но так как он возвращает те же данные, которые были возвращены во время предыдущего инициалаlogin - 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, с теми же данными или нет ... но он этого не делает.Так что я как бы застрял с этим - как заставить Аполлона реагировать на refetch моего запроса, чтобы я мог заново заполнить user в моем состоянии Container?

1 Ответ

0 голосов
/ 23 сентября 2019

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

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: [],
  },
})

LoginPage

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();
      }}

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

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

...