轮询不起作用时更新Apollo客户端3的缓存

问题描述

我正在使用@apollo/client v3的缓存。这是codesandbox

我正在使用client.writeQuery向缓存的用户列表中添加 user ,并且查询中有一个pollInterval每隔几秒钟重新提取一次。

我能够将用户添加到列表中,它确实刷新了UI,并且可以在Chrome的network标签中看到pollInterval。

问题

我希望在轮询开始时用户列表能够返回其初始状态,并覆盖我手动添加到缓存中的用户,但是不会。

Apollo配置

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>
  );
}

useUserList

const GET_USER_LIST = gql`
  query Users {
    users {
      id
      firstname
    }
  }
`;

export const useUserList = () => {
  const { loading,error,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,refetch };
};

解决方法

按预期工作(几乎)

轮询响应始终以相同数据 ...

到达

... 不会导致写入缓存(未比较内容)...

...缓存中没有数据更改...

... data属性(来自useQuery)未更新...

...没有更新data,没有重新呈现组件。

要使乐观更新正常工作,您需要一个真正的突变,远程数据源上的真正(持久)更改会传播到下一个轮询的响应。