使用以未定义缓存状态结尾的 apollo-cache-persist 和 apollo-link-state

Posted

技术标签:

【中文标题】使用以未定义缓存状态结尾的 apollo-cache-persist 和 apollo-link-state【英文标题】:Using apollo-cache-persist and apollo-link-state ending in undefined cache state 【发布时间】:2018-06-08 13:10:29 【问题描述】:

当我实际登录时,我可以运行 currentUser 查询并查看缓存中的令牌,但是当我刷新应用程序时,令牌返回 null

const currentUser = 
  defaults: 
    currentUser: 
      __typename: 'CurrentUser',
      token: null,
    ,
  ,
  resolvers: 
    Mutation: 
      updateCurrentUser: (_,  token ,  cache ) => 
        cache.writeData(
          data: 
            __typename: 'Mutation',
            currentUser: 
              __typename: 'CurrentUser',
              token,
            ,
          ,
        );

        return null;
      ,
    ,
  ,
;

export default currentUser;

我的客户端设置代码如下所示:

import  AsyncStorage  from 'react-native';
import 
  ApolloClient,
  HttpLink,
  InMemoryCache,
  IntrospectionFragmentMatcher,
 from 'apollo-client-preset';
import  Actions as RouterActions  from 'react-native-router-flux';
import  persistCache  from 'apollo-cache-persist';
import  propEq  from 'ramda';
import  setContext  from 'apollo-link-context';
import  withClientState  from 'apollo-link-state';

import fragmentTypes from './data/fragmentTypes';
import config from './config';
import  onCatch  from './lib/catchLink';
import  defaults, resolvers  from './resolvers';
import  CurrentUserQuery  from './graphql';

const cache = new InMemoryCache(
  fragmentMatcher: new IntrospectionFragmentMatcher(
    introspectionQueryResultData: fragmentTypes,
  ),
);

persistCache(
  cache,
  storage: AsyncStorage,
  trigger: 'write',
);

const httpLink = new HttpLink(
  uri: `$config.apiUrl/graphql`,
);

const stateLink = withClientState( cache, resolvers, defaults );

const contextLink = setContext((_,  headers ) => 
  const  currentUser:  token   = cache.readQuery(CurrentUserQuery());
  return 
    headers: 
      ...headers,
      authorization: token && `Bearer $token`,
    ,
  ;
);

const catchLink = onCatch(( networkError =  ) => 
  if (propEq('statusCode', 401, networkError)) 
    // remove cached token on 401 from the server
    RouterActions.unauthenticated( isSigningOut: true );
  
);

const link = stateLink
  .concat(contextLink)
  .concat(catchLink)
  .concat(httpLink);

export default new ApolloClient(
  link,
  cache,
);

【问题讨论】:

【参考方案1】:

为缓存补充水分是一项异步操作,可能是您的查询在缓存补充水分之前执行。

您可以等待persistCache,它会返回一个承诺,一旦缓存恢复,该承诺就会解决。

【讨论】:

【参考方案2】:

可能尝试使用 Apollo Link 包来加入链接。

import ApolloLink from 'apollo-link';
//....
//....
//....
const link = ApolloLink.from([stateLink,contextLink, catchLink, httpLink]);

PS:我已经写了一篇关于 apollo-link-state 的文章,如果你想看看https://hptechblogs.com/central-state-management-in-apollo-using-apollo-link-state/

【讨论】:

以上是关于使用以未定义缓存状态结尾的 apollo-cache-persist 和 apollo-link-state的主要内容,如果未能解决你的问题,请参考以下文章

使用以编程方式创建的自定义 UITableViewController 管理 UITableView

升级到 Rails 4.2.5.1 后 nil:NilClass 的未定义方法“缓存”

我想使用php 7.2使mcrypt在xampp窗口上工作错误:调用未定义的函数mcrypt_module_open()

使用以 10.0.0 形式定义版本号的宏

使用以编程方式创建的 segue IOS 调用自定义过渡动画师

图片网址未缓存