GraphQL 入门: 简介
GraphQL 入门: Apollo Client - 简介
GraphQL 入门: Apollo Client - 安装和配置选项
GraphQL 入门: Apollo Client - 链接到数据
GraphQL 入门: Apollo Client - 网络层
GraphQL 入门: Apollo Client - 开发调试工具
GraphQL 入门: Apollo Client - 持久化GraphQL查询概要
GraphQL 入门: Apollo Client - 存储API
GraphQL 入门: Apollo Client - 查询(Batching)合并html
Apollo Client
使用四个方法来控制存储:readQuery
, readFragment
, writeQuery
, writeFragment
. Apollo Client 的这些实例方法可让你直接读写缓存. react
用这四个方法可以让你自定义Apollo Client的行为. 下面咱们介绍每一个方法的细节.segmentfault
第一个和存储交互的方法是readQuery
. 该方法用于从根查询开始读取缓存数据, 下面是读取数据的例子:后端
const data = client.readQuery({ query: gql` { todo(id: 1) { id text completed } } ` });
若是数据在缓存中已经存储, 它将会直接返回并存储到组件的data
属性, 而不须要向服务器请求, 若是在缓存中找不到查询对应的数据, 将会抛出一个错误.api
你能够在应用中任何地方使用一个查询, 还能够传入变量:浏览器
import { TodoQuery } form './TodoGraphQL'; const data = client.readQuery({ query: TodoQuery, variables: { id: 5 } });
readQuery
和 query
相似, 可是readQuery
不会发送请求到服务器, 它老是指望从缓存中查询数据, 若是缓存中找不到对应的数据, 将会抛出一个错误.缓存
有时候你但愿重缓存中读取任意的数据, 而不单单是根查询类型. 对此有一个 readFragment()
方法用于这类用途. 该方法接受 GraphQL 片断和一个 ID, 并返回 ID 对应的数据片断.服务器
client.readFragment({ id: '5', fragment: gql` fragment todo on Todo { id text completed } ` });
id
应该是一个由 dataIdFromObject
函数返回的字符串, 这个字符串是在 Apollo Client 初始化的时候经过 dataIdFromObject
函数进行定义.网络
const client = new ApolloClient({ dataIdFromObject: o => { if(o.__typename != null && o.id != null) { return `${o.__typename}-${o.id}`; } } });
由于在id
前面添加了变量__typename
, 而后id
的值变为Todo5
.函数
和读取查询和片断对应的还有 writeQuery()
和 writeFragment()
方法. 这两个方法让你可以更新缓存中的数据, 用于模拟来自服务器的数据更新. 可是注意这些数据没有持久化到后端, 若是你刷新你的浏览器, 这些更新的数据将会丢失.
用户不会注意到有什么区别, 若是更新数据要对全部用户可见, 须要把更新的数据持久化到后端服务器.
writeQuery
和 writeFragment
的优势是, 它们让你可以修改缓存中的数据以确保数据可以同步到服务器, 而且在执行一次服务器彻底刷新的时候不会丢失你的数据更新. 这让你可以部分的修改客户端数据, 给用户提供更好的体验.
writeQuery()
和 readQuery
有相同的接口, 和 readQuery
不一样的是 writeQuery
还有一个 data
参数. data
对象的结构必须和服务器返回的JSON结果的结构相同.
client.writeQuery({ query: gql` { todo(id: 1) { completed } } `, data: { todo: { completed: true }, }, });
一样的, writeFragment()
和 readFragment()
也有相同的接口, 而且多一个 data
参数. id
遵循和 readFragment()
相同的规则:
client.writeFragment({ id: '5', fragment: gql` fragment todo in Todo { completed } `, data: { completed: true } });
这四个方法让你可以彻底的控制缓存中的数据.
由于从缓存中获取的数据只是一份拷贝, 不影响底层的存储.
const query = gql` { todos { id text completed } } `; const data = client.readQuery({ query }); data.todos.push({ id: 5, text: 'Hello, world!', completed: false }); client.writeQuery({ query, data });
const text = 'Hello, world!'; client.mutate({ // GraphQL Mutation 更新语句 mutation: gql` mutation ($text: String!) { createTodo(text: $text) { id text completed } } `, // 变量 variables: { text, }, optimisticResponse: { createTodo: { id: -1, // Fake id text, completed: false, }, }, // 更新函数 // 用Mutation返回的结果对存储进行更新, 并触发React UI组件的从新渲染 update: (proxy, mutationResult) => { const query = gql` { todos { id text completed } } `; // 从缓存中读取数据 const data = proxy.readQuery({ query, }); // 用Mutation的结果更新数据 data.todos.push(mutationResult.createTodo); // 写回缓存 proxy.writeQuery({ query, data, }); }, });
update
函数有两个参数:
proxy
是一个 DataProxy 对象, 主要用于与底层存储进行数据交互
mutationResult
是一个Mutation操做的响应, 能够是一个乐观应答, 或服务器实际的应答.
也可使用updateQueries
回调函数对数据进行更新. 详细的API接口可参考 updateQueries
updateQueries
也是基于 Mutation 的返回结果对存储进行更新, 和 update
函数不一样的是, 他会覆盖全部重叠的数据节点