更新后 Mutation 组件与商店不同步

Mutation component becomes out of sync with the store after updates

这段看似很长,其实很简单;它创建一个节点并呈现其数据,然后更新节点并呈现更新的数据,但是创建的数据不会更新,即使直接检查商店显示 createFoo 查询的商店有已更新。我想了解如何确保依赖于 Apollo 客户端存储的数据的组件是最新的,最好是自动更新。

const CREATE_FOO = gql`
  mutation {
    createFoo(data: {}) {
      id
      bar
    }
  }
`;

const UPDATE_FOO = gql`
  mutation($id: ID!) {
    updateFoo(where: { id: $id }, data: { bar: "baz" }) {
      id
      bar
    }
  }
`;

<Mutation mutation={CREATE_FOO}>
  {(createFoo, { data: createData }) => {
    if (createData) {
      return (
        <div>
          <p>{JSON.stringify(createData.createFoo)}</p>
          <Mutation
            mutation={UPDATE_FOO}
            variables={{ id: createData.createFoo.id }}
          >
            {(updateFoo, { data: updateData }) => {
              if (updateData) {
                return <p>{JSON.stringify(updateData.updateFoo)}</p>;
              }
              return (
                <button onClick={updateFoo} type="button">
                  updateFoo
                </button>
              );
            }}
          </Mutation>
        </div>
      );
    }
    return (
      <button onClick={createFoo} type="button">
        createFoo
      </button>
    );
  }}
</Mutation>

数据模型:

type Foo {
  id: ID! @unique
  bar: String
}

存储数据:

{
  "ROOT_QUERY": {
    "userSidebarWidth": 200
  },
  "Foo:cjqd2cd41zi140a98ugrjpz2m": {
    "id": "cjqd2cd41zi140a98ugrjpz2m",
    "bar": "baz",
    "__typename": "Foo"
  },
  "ROOT_MUTATION": {
    "createFoo({\"data\":{}})": {
      "type": "id",
      "generated": false,
      "id": "Foo:cjqd2cd41zi140a98ugrjpz2m",
      "typename": "Foo"
    },
    "updateFoo({\"data\":{\"bar\":\"baz\"},\"where\":{\"id\":\"cjqd2cd41zi140a98ugrjpz2m\"}})": {
      "type": "id",
      "generated": false,
      "id": "Foo:cjqd2cd41zi140a98ugrjpz2m",
      "typename": "Foo"
    }
  }
}

假设您有一个这样的 Query 组件:

const GET_FOO = gql`
  query SomeQuery {
    getFoo {
      id
      bar
    }
  }
`;

<Query query={GET_FOO}>
  {({ loading, error, data }) => (
    <SomeComponent/>
  )}
</Query>

挂载组件时,Apollo 从服务器或缓存中获取数据(取决于数据是否被缓存以及您的获取策略是什么)。但是,它也订阅 缓存中的更改。因此,如果您获取了一个 ID 为 1Foo,并且它通过另一个操作在缓存中进行了更新,组件将收到通知并相应地进行更新。具体来说,传递给 render prop 函数的 data 值将被更改以反映缓存中的更改。

Mutation 组件具有类似于 Query 组件的渲染属性函数签名,包括 data 属性。但是,这个属性只反映调用mutate函数时返回的数据。虽然突变的结果存储在缓存中,但通过 Mutation 组件公开的 data 不是订阅缓存的结果——相反,它只是一种对mutate 调用的结果。 Mutation 组件中的 data 唯一可能发生变化的情况是再次调用 mutate 函数。

如果我们修改您的示例并将组件包装在 Query 组件中,我们可以在您的组件内显示来自查询的数据,并可能忽略来自两个 [=] 之一的 data 15=] 组件。假设 QueryMutations 引用缓存中的相同项目,来自 Query 组件的数据将在任何一个突变解决时更新。