此处示例:https://codesandbox.io/s/j4mo8qpmrw
文档:https://www.apollographql.com/docs/link/links/state.html#default
TLDR:这是一个待办事项列表,@ client查询参数不会过滤掉列表。
这是查询,将$ id作为参数
const GET_TODOS = gql`
query todos($id: Int!) {
todos(id: $id) @client {
id
text
}
}
`;
查询传递那里的变量
<Query query={GET_TODOS} variables={{ id: 1 }}>
/* Code */
</Query>
但是默认解析器没有使用该参数,您可以在上面的codesandbox.io示例中看到它。
文档说它应该有用,但我似乎无法弄清楚我错过了什么。提前谢谢!
答案 0 :(得分:6)
对于简单的用例,您通常可以依靠the default resolver来获取所需的数据。但是,要实现诸如过滤缓存中的数据或操纵它(就像使用突变一样)之类的东西,您需要编写自己的解析器。为了完成你想要做的事情,你可以这样做:
export const resolvers = {
Query: {
todos: (obj, args, ctx) => {
const query = gql`
query GetTodos {
todos @client {
id
text
}
}
`
const { todos } = ctx.cache.readQuery({ query })
return todos.filter(todo => todo.id === args.id)
},
},
Mutation: {},
}
编辑:我们定义的每个类型都有一组字段。当我们返回特定类型(或类型列表)时,该类型上的每个字段将使用默认解析器来尝试解析其自己的值(假设该字段已被请求)。默认解析器的工作方式很简单 - 它查看父对象(或&#34; root&#34;)对象的值,如果找到与字段名称匹配的属性,则返回该属性的值。如果找不到该属性(或者无法将其强制转换为该字段所期望的标量或类型),则返回null。
这意味着我们可以,例如,返回代表单个Todo的对象,我们不必为其id
或text
字段定义解析器,只要该对象它上面有id
和text
个属性。换句话说,如果我们想在名为Todo
的{{1}}上创建一个任意字段,我们可以保留缓存默认值,并创建一个像
textWithFoo
在这种情况下,默认解析器对我们没有好处,因为存储在缓存中的对象不具有(obj, args, ctx) => obj.text + ' and FOO!'
属性,因此我们编写自己的解析器。
要记住的重要一点是textWithFoo
这样的查询也只是一个字段(在这种情况下,它是查询类型中的字段)。它的行为与其他任何字段的行为几乎相同(包括默认的解析器行为)。但是,使用todos
,您在apollo-link-state
下定义的数据结构将成为父级或&#34; root&#34;您的查询的价值。
在您的示例代码中,您的defaults
包含一个属性(defaults
)。因为它是根对象上的属性,所以我们可以使用名为todos
的查询来获取它,即使没有解析器也可以获取数据。 todos
字段的默认解析器将查看根对象(在本例中为缓存),请参阅名为todos
的属性并返回该属性。
另一方面,像todos
(单数)这样的查询在根(缓存)中没有匹配的属性。你需要为它编写一个解析器来让它返回数据。同样,如果您想在查询中返回数据之前操作数据(带或不带参数),则需要包含一个解析器。