如何将 localStorage 与 apollo-client 和 reactjs 一起使用?

Posted

技术标签:

【中文标题】如何将 localStorage 与 apollo-client 和 reactjs 一起使用?【英文标题】:How to use localStorage with apollo-client and reactjs? 【发布时间】:2020-03-31 08:38:24 【问题描述】:

我需要使用 reactjs 和 apollo-client 为在线商店制作购物车。 如何使用 apollo-client 和 localStorage 持久化数据?

【问题讨论】:

本地存储只能在客户端工作。如果您在会话之后仍在寻找持久值,那么您必须将其发送到服务器 我可以在 apollo 客户端的帮助下将数据保存到 localStorage 吗? 是的,您可以使用 apollo-cache-persist 来持久化缓存。您可以查看github.com/apollographql/apollo-cache-persist 给出的示例 建议:可以使用 contextAPI reactjs.org/docs/context.html 或者 redux store。 【参考方案1】:

文档: https://github.com/apollographql/apollo-cache-persist

import  InMemoryCache  from 'apollo-cache-inmemory';
import  persistCache  from 'apollo-cache-persist';

const cache = new InMemoryCache(...);

// await before instantiating ApolloClient, else queries might run before the cache is persisted
await persistCache(
  cache,
  storage: window.localStorage,
);

// Continue setting up Apollo as usual.

const client = new ApolloClient(
  cache,
  ...
);

【讨论】:

【参考方案2】:

是的,您可以使用 localStorage 来持久化 Apollo 客户端缓存。 apollo-cache-persist 可用于所有 Apollo Client 2.0 缓存实现,包括 InMemoryCache 和 Hermes。

这是一个工作示例,展示了如何使用Apollo GraphQL client 管理本地状态以及如何使用apollo-cache-persist 将缓存持久化到localStorage。

import React from 'react';
import ReactDOM from 'react-dom';

import  ApolloClient  from 'apollo-client';
import  InMemoryCache  from 'apollo-cache-inmemory';
import  createHttpLink  from 'apollo-link-http';
import  ApolloProvider  from '@apollo/react-hooks';
import  persistCache  from 'apollo-cache-persist';

import  typeDefs  from './graphql/schema';
import  resolvers  from './graphql/resolvers';
import  GET_SELECTED_COUNTRIES  from './graphql/queries';

import App from './components/App';

const httpLink = createHttpLink(
  uri: 'https://countries.trevorblades.com'
);

const cache = new InMemoryCache();

const init = async () => 
  await persistCache(
    cache,
    storage: window.localStorage
  );

  const client = new ApolloClient(
    link: httpLink,
    cache,
    typeDefs,
    resolvers
  );

  /* Initialize the local state if not yet */
  try 
    cache.readQuery(
      query: GET_SELECTED_COUNTRIES
    );
   catch (error) 
    cache.writeData(
      data: 
        selectedCountries: []
      
    );
  

  const ApolloApp = () => (
    <ApolloProvider client=client>
      <App />
    </ApolloProvider>
  );

  ReactDOM.render(<ApolloApp />, document.getElementById('root'));
;

init();

您可以在 my GitHub Repo 上找到此示例。

顺便说一下,应用看起来是这样的:

它的 localStorage 在 Chrome DevTools 中如下所示:

【讨论】:

【参考方案3】:

我知道我来晚了,但我找到了使用最新版本处理此问题的完美方法:apollo3-cache-persist

这是我的代码:(记得导入这些模块)

const cache = new InMemoryCache();

const client = new ApolloClient(
    //your settings here
);

const initData = 
  //your initial state

client.writeData(
    data: initData
);

//persistCache is asynchronous so it returns a promise which you have to resolve
persistCache(
    cache,
    storage: window.localStorage
).then(() => 
    client.onResetStore(async () => cache.writeData(
        data: initData
    ));
    
);

更多信息请阅读documentation这里,它将帮助您快速设置。

【讨论】:

以上是关于如何将 localStorage 与 apollo-client 和 reactjs 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将服务注入 apollo-client 的中间件?

如何将 Apollo 客户端与 AppSync 一起使用?

如何将 Apollo 与 NativeScript vue 集成?

将 Apollo for iOS 与现有项目集成?

如何将 Angular/Apollo 客户端与 graphene-django 集成?

Apollo GraphQL 的动态标头(中间件之外)