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
测试在模块所在的同一目录中定义。它们在“[module].test.js”文件中指定。
要构建项目,请执行
npm run build
这会将生产就绪代码保存到“dist/”中。