#caching #react-apollo #apollo-client #apollo-cache-inmemory
#кэширование #реагировать-apollo #apollo-client #apollo-cache-inmemory
Вопрос:
Я использую refetch()
всякий раз, когда переменные useQuery изменяются для фильтрации списка. Каждый раз, когда изменяется переменная prop, она извлекает результаты в соответствии с фильтрами, когда результаты с сервера являются пустым списком [] , метод refetch() возвращает кэшированные результаты, а не пустой список [] .
const { loading, error, data, fetchMore, refetch } = useQuery(Users, {
variables: {
userNumber: userNum,
},
});
useEffect(() => {
if (userNum){
refetch();
}
}, [userNum]);
Таким образом, он извлекает обновленный результат каждый раз, когда пользовательский реквизит изменяется со списком пользователей, у которых есть этот номер пользователя. однако, если список пользователей, возвращенных с сервера, пуст (поскольку ни у одного пользователя нет этого номера), я вижу предыдущие кэшированные результаты вместо пустого списка.
Я пробовал
fetchPolicy: 'cache-and-network',
nextFetchPolicy: 'cache-first',
и все равно получаем кэшированные результаты вместо пустого списка.
Я также попробовал merge() в typePolicies, и это сработало! Однако, когда я применяю relayStylePagination, он снова извлекает кэшированные результаты, а не пустой список.
uri: 'http://localhost:5000/graphql',
cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
devices: relayStylePagination(),
merge(existing = {}, incoming) {
return { ...existing, ...incoming };
},
},
},
},
}),
});
Я также пробовал с ключевыми полями и снова работает, кэш обновляется, когда сервер возвращает пустой список, однако нумерация страниц реле не работает. Единственный способ заставить ретрансляционную разбивку на страницы работать — размещать ее только так:
fields: {
devices: relayStylePagination(),
},
`
Мой запрос выглядит следующим образом:
$after: ID
$userNum: Int
$dpiGt: String
$dpiLt: String
) {
users(
after: $after
userNumber: $userNum
first: 30
filter: { dpiGt: $dpiGt, dpiLt: $dpiLt }
) {
edges {
cursor
node {
id
name
userNumber
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
Сведения о системе:
OS: macOS 10.15.4
Binaries:
Node: 12.16.1 - ~/n/bin/node
Yarn: 1.21.1 - /usr/local/bin/yarn
npm: 6.13.4 - ~/n/bin/npm
Browsers:
Chrome: 86.0.4240.80
Firefox: 81.0.1
Safari: 13.1
npmPackages:
@apollo/client: ^3.2.3 => 3.2.5
Комментарии:
1. Вы решили это?
Ответ №1:
Не уверен, что это решит вашу проблему, но стоит попробовать.
После изучения и прочтения документации Apollo в разделе повторная выборка я нашел это описание, которое может быть полезно для вашего варианта использования.
К счастью, объект результата перехвата useQuery предоставляет детализированную информацию о состоянии запроса через свойство NetworkStatus. Чтобы воспользоваться преимуществами этой информации, нам нужно установить для параметра notifyOnNetworkStatusChange значение true, чтобы наш компонент запроса повторно отображал, пока выполняется повторная выборка:
import { useQuery, NetworkStatus } from '@apollo/client';
...
const { loading, error, data, fetchMore, refetch, networkStatus } = useQuery(Users, {
variables: {
userNumber: userNum,
},
notifyOnNetworkStatusChange: true,
});
if (networkStatus === NetworkStatus.refetch) return <div>Refetching!</div>;
...