Apollo 缓存查询字段策略 offsetLimitPagination() 不适用于订阅

Apollo cache query fields policy offsetLimitPagination() doesnt work with subscriptions

我使用 apollo 客户端来响应本机。

当我使用 offsetLimitPagination() 进行分页时,我的订阅不会更新缓存。

订阅工作正常但不更新 flatlist 数据。 当我删除 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 客户端一个密钥“根据内容缓存,因为每个房间都有一个 id 或 roomName for keyArgs param 它应该是唯一的值

const cache = new InMemoryCache({
typePolicies: {
   Query: {
      fields: {
         
         chatDetail: {
                keyArgs:['roomId'],
                merge(incoming=[], existing=[]){
               
               .
               .
               .
               return offsetLimitPagination()
       }}
    }
  }
 },
});