如何在单个项目中使用多个版本的 Apollo 客户端

how to use multiple versions of Apollo client in single project

我正在接管一个较旧的 React/Apollo/GraphQL 项目,该项目目前没有使用 useQuery、useMutation 等钩子。所以我正在尝试进行升级。

我已经安装了包@apollo/react-hooks,并在我的 App.js

中替换了 ApolloProvider
//import { ApolloProvider } from 'react-apollo'; //Old
import { ApolloProvider } from '@apollo/react-hooks'; //New

<ApolloProvider client={apolloClient}>......</ApolloProvider>

然而,当 运行 应用程序时,这会导致错误:

index.mjs?8baf:1 Uncaught ReferenceError: 模块未定义 在 eval (index.mjs?8baf:1) 在 Module../node_modules/graphql/index.mjs(供应商。aa829d69df1a68216354.js:7568) 在 webpack_require(应用程序aa829d69df1a68216354.js:780) 在 fn (app.aa829d69df1a68216354.js:148) 在评估 (index.js:3) 在对象../node_modules/@apollo/client/utilities/index.js

我的 package.json 有以下相关包:

"react-apollo": "^2.0.1",
"react": "^16.14.0",
"apollo-cache-inmemory": "^1.1.12",
"apollo-client": "^2.6.10",
"@apollo/react-hooks": "^4.0.0",
"apollo-link": "^1.2.2",
"apollo-link-batch-http": "^1.2.2",
"apollo-link-context": "^1.0.8",
"apollo-link-error": "^1.0.9",
"apollo-link-http": "^1.5.4",
"apollo-link-ws": "^1.0.8",
"apollo-utilities": "^1.0.11"

如果我尝试使用 'react-apollo' 中的 ApolloProvider,我可以 运行 我的应用程序,但是在添加时:

import {useQuery} from '@apollo/react-hooks';

应用程序无法加载。

我希望有人有过同样的经历谁有解决方案..在此先感谢

也许您需要再次阅读 Apollo 文档。

这是 Introduction to Apollo Client for React 的 link。

取自Apollo Docs for React:

import React from 'react';
import { render } from 'react-dom';

import { ApolloProvider } from '@apollo/client';

function App() {
  return (
    <ApolloProvider client={client}>
      <div>
        <h2>My first Apollo app </h2>
      </div>
    </ApolloProvider>
  );
}

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

您需要从 @apollo/client 而不是 @apollo/react-hooks 导入 ApolloProvider

并尝试安装所有与 apollo react 相关的版本 4。否则,您可能会像我一样遇到很多错误 here


编辑:

如果您想在逐步重构代码时结合这两个版本,请尝试将使用 Apollo v4 创建的 client 直接提供给挂钩。这是我们目前在工作中使用的方法。

useQueryuseMutationoptions 对象,可以使用 client 实例。因此,尝试使用新的 Apollo v4 包创建一个新的 client 实例,而不是将这个新的 client 传递给 ApolloProvider,而是在每个组件中导入客户端并将其提供给挂钩显式使用 options 对象。完成对钩子的重构后,您可以将组件包装在 ApolloProvider 中并删除 options 对象中的 client 实例(即使您不删除它,它也可以正常工作,直到您继续在 ApolloProvideruseQuery 以及 useMutationoptions 对象中使用相同的 client(Apollo v4) 实例。


编辑:2

问题是您当前使用的是 Apollo Client v2.6。但较新的版本是 Apollo Client v3.x。而新版本的 @apollo/react-hooks 显然希望你使用最新的 Apollo Client v3.x.

因此,您需要维护两个 apollo 客户端文件,直到您重构整个代码库以响应挂钩。

  1. 使用 apollo-client^2 - 与您现有的代码(您已经拥有)一起使用
  2. 使用@apollo/client^3 - 与 apollo 挂钩一起使用

当你这样做时,

<ApolloProvider client={oldClientCreatedUsingv2}>
      <div>
        <h2>My first Apollo app </h2>
      </div>
</ApolloProvider>

useQueryuseMutation 挂钩使用 ApolloProvider 中提供的 client。但是显然你不能将它用于两个 ApolloProviders 版本。会有冲突。

因此,在 ApolloProvider 中提供您的 v2 apollo 客户端实例,这样您现有的代码库就不会受到干扰。 事实上,您甚至不必在此处修改任何内容。就这样吧。

并在 useQueryuseMutation 中提供 v3 apollo 客户端实例(即,使用 @apollo/client 创建客户端,如 this)。 这是您唯一需要做的事情。

接下来,在使用钩子进行查询或变更时,像这样在任何地方提供使用 v3 创建的客户端:

const {loading, error, data } = useQuery(YOUR_QUERY, { client: newClientCreatedUsingv3 });

ApolloProvider只是用来向下传递client,这样我们就不用在每个组件中都引入它,传递给useQuery和[=的钩子了19=] 或 HOC.

如果您在发出请求时明确提供客户端,则它不会使用 ApolloProvider 中提供的客户端。

一旦您将代码完全重构为使用 React Hook,您就可以像这样更改 ApolloProvider

<ApolloProvider client={newClientCreatedUsingv3}>
      <div>
        <h2>My first Apollo app </h2>
      </div>
</ApolloProvider>

现在,您可以从每个 useQueryuseMutation 中删除 client 选项,以便从现在开始进一步清理代码 useQueryuseMuation 将开始使用 ApolloProvider.

中提供的 newClientCreatedUsingv3 实例

希望这能说明问题。