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
函數不一樣的是, 他會覆蓋全部重疊的數據節點