Apollo-Offline 提供了自訂網路介面和 Redux 儲存增強器,可使用 Apollo GraphQL 用戶端實現無縫的離線優先應用程式開發。
Apollo-Offline 建構在 Redux-Offline 之上(因此繼承了它的所有功能)。
它的目的是利用 Apollo 現有的離線功能(例如內建快取和對突變的樂觀響應)。這意味著遷移時,您的程式碼不必進行太多更改(只要您已經在使用這些功能)。
使用 Apollo-Offline,您的查詢和突變程式碼看起來與沒有 Apollo-Offline 時完全一樣。
但有一個例外: 「樂觀獲取」功能。
「樂觀獲取」的作用是首先嘗試從快取中讀取查詢的回應,但如果(且僅當!)網路連線可用時,它將在後台獲取伺服器的回應並將其寫入快取(此時例如,包裝的React 元件將第二次更新)。
基本上,這意味著如果請求的資料在本地快取中可用,您的 UI 查詢將始終有效,並且如果可以訪問,它將始終使快取資料與伺服器資料保持一致。
注意:在我看來,這就是fetchPolicy: 'cache-and-network'
應該做的(但沒有 - 如果無法訪問伺服器,則會出錯)。
若要啟用它,請將具有真值的__offline__
欄位新增至該特定查詢的查詢變數(即variables: { __offline__: true }
)。
有關更多說明,請參閱下面的範例。
使用紗線
yarn add apollo-offline
或 npm
npm install --save apollo-offline
Apollo-Offline 也要求您安裝以下對等相依性:
apollo-client
redux
import { ApolloClient , createNetworkInterface } from 'apollo-client' ;
import { applyMiddleware , combineReducers , compose , createStore } from 'redux' ;
import config from '@redux-offline/redux-offline/lib/defaults' ;
import offline from 'apollo-offline' ;
// 1. Wrap your network interface
const { enhancer , networkInterface } = offline (
createNetworkInterface ( {
uri : `http://localhost` ,
} ) ,
) ;
// 2. Create your Apollo client
const client = new ApolloClient ( {
/* Your Apollo configuration here... */
networkInterface ,
} ) ;
// 3. Pass the client to the offline network interface
// (Optional, but needed for the optimistic fetch feature)
networkInterface . setClient ( client ) ;
// 4. Create your redux store
export const store = createStore (
combineReducers ( {
apollo : client . reducer ( ) ,
} ) ,
undefined ,
compose (
applyMiddleware ( client . middleware ( ) ) ,
// Apply offline store enhancer
// (You can pass your own redux-offline config, but the default one is a good starting point)
enhancer ( config ) ,
) ,
) ;
注意:設定後,apollo-offline 會攔截所有查詢/突變,以實現無縫的離線優先行為。
如果您想要選擇性地從中排除某些查詢/突變,您可以透過在該特定查詢/突變的查詢變數中新增一個具有真值的__online__
欄位來還原為 Apollo 的預設行為(即variables: { __online__: true }
) 。
/* Setup goes here... */
// Queries
client . query ( { query : /* Your query here */ } ) ;
// - Using optimistic fetch feature
client . query ( {
fetchPolicy : 'network-only' ,
query : /* Your query here */ ,
variables : {
__offline__ : true , // Enable optimistic fetch
} ,
} ) ;
// Mutations
client . mutate ( {
mutation : /* Your mutation here */ ,
optimisticResponse : /* Your optimistic response here */ ,
update : /* Your update resolver here */ ,
} ) ;
在你的入口點:
/* Setup goes here... */
import { ApolloProvider } from 'react-apollo' ;
import { connect } from 'react-redux' ;
import App from './App' ; // Your main application component
// Component to postpone render until after Redux state has been rehydrated
const Rehydrated = connect ( ( { rehydrated } ) => ( { rehydrated } ) )
( ( props ) => props . rehydrated ? props . children : props . loading ) ;
const Loading = ( ) => < div > Loading... </ div > ;
ReactDOM . render (
< ApolloProvider client = { client } store = { store } >
< Rehydrated loading = { < Loading /> } >
< App />
</ Rehydrated >
</ ApolloProvider > ,
document . getElementById ( 'root' ) ,
) ;
包裝組件時:
import React from 'react' ;
import { graphql } from 'react-apollo' ;
// Queries
const wrappedComponent = graphql ( /* Your query here */ ) ( /* Your component here */ ) ;
// - Using optimistic fetch feature
const wrappedComponent = graphql (
/* Your query here */ ,
{
options : {
fetchPolicy : 'network-only' ,
variables : {
__offline__ : true , // Enable optimistic fetch
} ,
} ,
} ,
) ( /* Your component here */ ) ;
// Mutations (you will want to provide an optimistic response when executing them)
const wrappedComponent = graphql (
/* Your mutation here */ ,
{
options : {
update : /* Your update resolver here */ ,
} ,
} ,
) ( /* Your component here */ ) ;
這是克隆存儲庫後要做的事情:
yarn / npm install
(安裝依賴項)
執行 TSLint
npm run lint
嘗試自動修復 linting 錯誤
npm run lint:fix
使用執行 Jest 單元測試
npm test
npm run test:coverage
測試在模組所在的相同目錄中定義。
若要建置項目,請執行
npm run build
這會將生產就緒的程式碼儲存到“dist/”中。