首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阿波罗是否缓存从突变中返回的数据?

阿波罗是否缓存从突变中返回的数据?
EN

Stack Overflow用户
提问于 2020-12-01 18:07:53
回答 1查看 1.1K关注 0票数 1

我在一个React应用程序中使用阿波罗客户端,我需要做一个突变,然后保存返回的数据供以后使用(但我不能访问变量),我必须使用另一个状态管理解决方案,还是我们可以在阿波罗中这样做?

我读过关于用查询而不是变异来做这件事的文章。

到目前为止这是我的代码

代码语言:javascript
复制
// Mutation
const [myMutation, { data, errors, loading }] = useMutation(MY_MUTATION, {
    onCompleted({ myMutation }) {
      console.log('myMutation: ', myMutation.dataToKeep);
      if (myMutation && myMutation.dataToKeep)
        SetResponse(myMutation.dataToKeep);
    },
    onError(error) {
      console.error('error: ', error);
    },
  });

//How I call it

  onClick={() => {
    myMutation({
      variables: {
        input: {
          phoneNumber: '0000000000',
          id: '0000',
        },
      },
    });
  }}

编辑:

这是突变

代码语言:javascript
复制
export const MY_MUTATION = gql`
  mutation MyMutation($input: MyMutationInput!) {
    myMutation(input: $input) {
      dataToKeep
      expiresAt
    }
  }
`;

以及这种突变的模式

代码语言:javascript
复制
MyMutationInput:
  phoneNumber: String!
  id: String!

MyMutationPayload:
  dataToKeep
  expiresAt
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-01 18:27:03

案例1:有效载荷使用公共实体

简单地说,阿波罗客户端的缓存保存了从查询和突变中接收到的所有信息,尽管模式需要包含id: ID!字段,任何查询都需要在相关节点上同时使用id__typename字段,以便客户机知道要更新的缓存的哪一部分。

这假设突变有效负载是可以通过普通查询检索的架构中的公共数据。这是最好的情况。

给定服务器上的下列架构:

代码语言:javascript
复制
type User {
  id: ID!
  phoneNumber: String!
}

type Query {
  user(id: String!): User!
}

type UpdateUserPayload {
  user: User!
}

type Mutation {
  updateUser(id: String!, phoneNumber: String!): UpdateUserPayload!
}

假设一个缓存用于客户端。

代码语言:javascript
复制
import { InMemoryCache, ApolloClient } from '@apollo/client';

const client = new ApolloClient({
  // ...other arguments...
  cache: new InMemoryCache(options)
});

  1. 响应中包含的每个可识别对象的缓存生成唯一的ID。
  2. 缓存按ID将对象存储在平面查找表中。
  3. 每当传入对象以与现有对象相同的ID存储时,这些对象的字段将被合并。
代码语言:javascript
复制
- If the incoming object and the existing object share any fields, the incoming object _overwrites_ the cached values for those fields.
- Fields that appear in _only_ the existing object or _only_ the incoming object are preserved.

规范化在客户端上构建数据图的部分副本,格式优化,以便在应用程序更改状态时读取和更新图表。

客户的突变应该是

代码语言:javascript
复制
mutation UpdateUserPhone($phoneNumber: String!, $id: String!) {
  updateUser(id: $id, phoneNumber: $phoneNumber) {
    user {
      __typename  # Added by default by the Apollo client
      id          # Required to identify the user in the cache
      phoneNumber # Field that'll be updated in the cache
    }
  }
}

然后,通过应用程序中相同的阿波罗客户端使用该用户的任何组件都将自动更新。没有什么特别的事情要做,客户端将在默认情况下使用缓存并在数据更改时触发呈现。

代码语言:javascript
复制
import { gql, useQuery } from '@apollo/client';

const USER_QUERY = gql`
  query GetUser($id: String!) {
    user(id: $id) {
      __typename
      id
      phoneNumber
    }
  }
`;

const UserComponent = ({ userId }) => {
  const { loading, error, data } = useQuery(USER_QUERY, {
    variables: { id: userId },
  });

  if (loading) return null;
  if (error) return `Error! ${error}`;

  return <div>{data.user.phoneNumber}</div>;
}

选项默认为cache-first

案例2:有效载荷是特定于突变的自定义数据

如果数据实际上在架构的其他地方不可用,就不可能像上面解释的那样自动使用阿波罗缓存。

使用另一种状态管理解决方案

有几个选择:

下面是一个使用阿波罗GraphQL文档中的示例localStorage

代码语言:javascript
复制
const [login, { loading, error }] = useMutation(LOGIN_USER, {
  onCompleted({ login }) {
    localStorage.setItem('token', login.token);
    localStorage.setItem('userId', login.id);
  }
});

定义客户端架构。

这是一个纯阿波罗GraphQL解决方案,因为客户端也是一个状态管理库,它支持有用的开发工具并帮助对数据进行推理。

  1. 创建本地架构。 // schema.js export = gqltype DataToKeep { # anything here } extend type Query { dataToKeep: DataToKeep # probably nullable? }
  2. 初始化自定义缓存 // cache.js export = makeVar(null);export =新InMemoryCache({ typePolicies:{查询:{typePolicies:{ dataToKeep:{ read() {返回dataToKeepVar();} },});
  3. 在客户端初始化时应用架构覆盖 从“@ InMemoryCache / client”导入{ typeDefs };从“./ cache”导入{ typeDefs };从“./schema”导入{typeDefs};从“ApolloClient”导入{typeDefs}({ cache、typeDefs、/其他选项,如头、uri等);
  4. 跟踪突变的变化: myMutation,{ data,errors,loading }= useMutation(MY_MUTATION,{ onCompleted({ myMutation }) ){ if (myMutation & myMutation.dataToKeep) dataToKeepVar(myMutation.dataToKeep);};
  5. 然后,查询@client字段。 从@阿波罗/客户端导入{ gql,useQuery };const DATA_QUERY = gqlquery dataToKeep { dataToKeep @client { # anything here } };const AnyComponent = ({ userId }) => { const { loading,error,data }= useQuery(DATA_QUERY);如果(加载)返回null;如果(错误)返回Error! ${error};返回{JSON.stringify(data.dataToKeep)};

还请参阅关于管理地方政府的文档。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65096075

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档