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();
}}
Для получения дополнительной информации об управлении местным государством. Проверьте это.
Надеюсь это поможет!