react-native - Apollo 缓存查询字段策略 offsetLimitPagination() 不适用于订阅
问题描述
我使用 apollo 客户端进行原生反应。
当我使用 offsetLimitPagination() 进行分页时,我的订阅不会更新缓存。
订阅可以正常工作,但不会更新平面列表数据。当我删除 offsetLimitPagination 函数时,它可以工作。我不能在缓存上同时使用订阅和 offsetLimitPagination 函数。
有什么解决办法吗?
谢谢。
缓存
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
chatDetail: offsetLimitPagination(),
}
}
},
});
聊天详情页
import React, { useState, useCallback } from 'react'
import { StyleSheet, Text, View, FlatList } from 'react-native'
import { ActivityIndicator } from 'react-native-paper';
import { useQuery } from '@apollo/client'
import { useSelector } from 'react-redux'
import { CHAT_DETAIL } from '../../../Graphql/Queries/Message'
import { MESSAGE_SUB } from '../../../Graphql/Subscriptions/Message'
import MainFlow from './Components/Flow/MainFlow'
const ChatDetailMain = () => {
const user = useSelector(state => state.auth.user)
const currentRoom = useSelector(state => state.room.currentRoom)
const [hasNext, setHasNext] = useState(true)
const limit = 15
const { error, loading, data, refetch, fetchMore, subscribeToMore } = useQuery(CHAT_DETAIL, {
variables: { userId: user._id, roomId: currentRoom._id, limit }, fetchPolicy: "cache-and-
network",
nextFetchPolicy: "cache-first" })
// render item
const renderItem = (
({item} ) => {
return <MainFlow item={item} />
}
)
if (error) {
console.warn('CHAT_DETAIL QUERY ERROR: ', error)
console.log(error.message);
return (
<View>
<Text>
An Error Occured: {error.message}
</Text>
</View>
)
}
if (loading || data == undefined || data == null) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<ActivityIndicator size={50} color="gray" />
</View>
)
}
// fetchMore
const fetchMoreData=()=>{
// console.log("fetchMore runnig hasnext limit, data.chatDetail.length >= limit ", hasNext, limit, data.chatDetail.length >= limit);
if(hasNext && data.chatDetail.length >= limit){
fetchMore({
variables:{
offset: data.chatDetail.length,
limit: data.chatDetail.length+limit
}
}).then((flowMoredata)=>{
if(flowMoredata.data.chatDetail.length==0 || flowMoredata.data.chatDetail.length === data.chatDetail.length){
setHasNext(false)
}
})
}
}
// subscription area
const subscribeQ = () => subscribeToMore({
document: MESSAGE_SUB,
variables: {
userId: user._id
},
updateQuery: (prev, { subscriptionData }) => {
if (!subscriptionData.data) return prev;
const { messageSub } = subscriptionData.data
let current = {}
let others = []
switch(messageSub.type){
case 'update':
prev.chatDetail.map(message => {
if (message._id != messageSub.message._id) others.push(message)
if (message._id == messageSub.message._id) current = messageSub.message
})
return { chatDetail: [ current, ...others ]}
case 'remove':
prev.chatDetail.map(message => {
if (message._id != messageSub.message._id) others.push(message)
if (message._id == messageSub.message._id) current = messageSub.message
})
return { chatDetail: [ ...others ]}
case 'create':
return { chatDetail: { ...prev, chatDetail: [ messageSub.message, ...prev.chatDetail] }}
default: return { ...prev }
}
}
})
if (subscribeToMore != undefined && subscribeToMore) {
subscribeQ()
}
return (
<View>
<FlatList
data={data.chatDetail}
renderItem={renderItem}
keyExtractor={(item, index) => String(index)}
onEndReached={fetchMoreData}
onEndReachedThreshold={0.2}
contentContainerStyle={{ paddingTop: 80 }}
inverted={true}
/>
</View>
)
}
export default ChatDetailMain
const styles = StyleSheet.create({})
解决方案
这是关于缓存合并问题。如果你想缓存数据,你应该给 apollo 客户端一个密钥“根据什么缓存,因为每个房间都有一个 keyArgs 参数的 id 或 roomName它应该像这样的唯一值
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
chatDetail: {
keyArgs:['roomId'],
merge(incoming=[], existing=[]){
.
.
.
return offsetLimitPagination()
}}
}
}
},
});
推荐阅读
- android - 如何从我的设备获取内存类型信息?
- java - Gradle 覆盖默认检查任务
- docker - Kaniko:如何使用 Tekton 在 Kubernetes 中缓存来自 Gatsby 构建的文件夹?
- swift - 如何在swift中调用mac API“添加新事件”?
- python - 不满足可选依赖项:安装 igraph 和 leidenalg 以使用所选功能
- html - 不透明的 GIF 变透明
- arrays - 在 BigQuery 中选择除 ARRAY_AGG + STRUCT 中的一列之外的所有内容
- c - 如果在同一个套接字上设置多个连接,哪个套接字描述符接收数据?
- python - Pandas Dataframe(内部)加入同一个 Dataframe
- node.js - MongoDB 领域 BadChangeSet 错误:无法验证上传变更集:ProtocolErrorCode=212