轮询不工作时更新 Apollo 客户端 3 的缓存
Posted
技术标签:
【中文标题】轮询不工作时更新 Apollo 客户端 3 的缓存【英文标题】:Update the cache of Apollo client 3 when polling not working 【发布时间】:2021-01-18 09:12:00 【问题描述】:我正在玩@apollo/client
v3 的缓存。这是codesandbox。
我正在使用client.writeQuery
将一个用户添加到缓存的用户列表中,并且查询有一个pollInterval
每隔几秒重新获取一次。
我可以将用户添加到列表中,它会刷新 UI,并且我可以看到 pollInterval 在 Chrome 的 network
选项卡中工作。
问题
我希望用户列表在轮询开始时返回到其初始状态,并覆盖我手动添加到缓存中的用户,但事实并非如此。
阿波罗配置
export const cache = new InMemoryCache();
const client = new ApolloClient(
cache,
link: new HttpLink(
uri: "https://fakeql.com/graphql/218375d695835e0850a14a3c505a6447"
)
);
用户列表
export const UserList = () =>
const optimisticAddUserToCache, data, loading = useUserList();
if (loading)
return <div>Loading...</div>;
return (
<div>
<button onClick=() => optimisticAddUserToCache()>Add User to cache</button>
<ol>
data?.users.map(user =>
return <li key=user.id>user.firstname</li>;
)
</ol>
</div>
);
使用用户列表
const GET_USER_LIST = gql`
query Users
users
id
firstname
`;
export const useUserList = () =>
const loading, error, data, refetch = useQuery(GET_USER_LIST,
pollInterval: 4000 // It does poll (check chromes's network tab), but it doesn't seem to overwrite the cache
);
const client = useApolloClient();
const optimisticAddUserToCache = () =>
const newUser: any =
id: `userId-$Math.random()`,
firstname: "JOHN DOE",
__typename: "User"
;
const currentUserList = client.readQuery( query: GET_USER_LIST ).users;
// This works, it does add a user, and UI refreshes.
client.writeQuery(
query: GET_USER_LIST,
data:
users: [newUser, ...currentUserList]
);
;
return optimisticAddUserToCache, loading, error, data, refetch ;
;
【问题讨论】:
【参考方案1】:按预期工作(几乎)
轮询响应总是带有相同的数据 ...
... 不会导致写入缓存(不比较内容)...
...缓存中没有数据更改...
...data
属性(来自useQuery
)未更新...
...没有data
更新,没有组件重新渲染。
要进行乐观更新,您需要真正的突变,远程数据源上的真正[持久]更改...传播到下一个轮询响应。
【讨论】:
这是我正在开发的一个大型应用程序的简短版本。在应用程序中,我正在做完全相同的事情,它有时有效,有时没有。我不知道为什么。但我可以告诉你,我从不对数据使用突变。为什么“......不会导致写入缓存(没有比较内容)......”?轮询数据实际上与缓存中的数据不同,因此应该进行比较?我很确定有一个不使用突变的解决方案,因为我说过我不使用它们并且它在我的应用程序中间歇性地工作。 轮询数据等于先前轮询的数据...响应数据未与缓存条目进行比较...可能应该进行比较(在 github 上发布问题?)...外部突变源?为什么不使用订阅(而不是轮询)? 我也在github上发帖以防万一。我只使用 GraphQL 来读取数据,而不是写入,因此我根本不使用突变。我们也有订阅,但在这种特殊情况下,我真的想了解缓存是如何工作的,所以除非我正在做的方式是绝对不可能的(我不这么认为,正如我所说的我有这一半在我的主应用程序上工作),我真的很想让我的示例工作。 看起来与github.com/apollographql/apollo-client/issues/6925相关以上是关于轮询不工作时更新 Apollo 客户端 3 的缓存的主要内容,如果未能解决你的问题,请参考以下文章
Apollo 客户端:更新缓存时的 writeFragment 或 readFragment?