在上下文中找不到“客户端”或在使用订阅时作为选项问题传入

问题描述

我需要实时获取一些数据。所以我决定使用WebSocket连接

import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloLink,split } from "apollo-link";
import { WebSocketLink } from "apollo-link-ws";
import { HttpLink } from "apollo-link-http";
import { setContext } from "apollo-link-context";
import { firebaseAppAuth } from "../../App";
import { onError } from "apollo-link-error";
import { getMainDeFinition } from "apollo-utilities";

import config from "../../config";

const authLink = setContext((_,{ headers }) => {
  //it will always get unexpired version of the token
  if (firebaseAppAuth && firebaseAppAuth.currentUser) {
    return firebaseAppAuth.currentUser.getIdToken().then((token) => {
      return {
        headers: {
          ...headers,"content-type": "application/json",authorization: token ? `Bearer ${token}` : "",},};
    });
  } else {
    return {
      headers: {
        ...headers,};
  }
});

const errLink = onError(({ graphQLErrors,networkError }) => {
  console.log(graphQLErrors);
  console.log(networkError);
  if (graphQLErrors)
    graphQLErrors.forEach(({ message,locations,path }) => {
      console.log(
        `[GraphQL error]: Message: ${message},Location: ${locations},Path: ${path}`
      );
    });
  if (networkError) {
    console.log(`[Network error]: ${networkError}`);
  }
});

const httpLink = new HttpLink({
  uri: config.adminAPI,});

const wsLink = new WebSocketLink({
  uri: config.apiSocket,// use wss for a secure endpoint
  options: {
    reconnect: true,});

const splittedLink = split(
  // split based on operation type
  ({ query }) => {
    const { kind,operation } = getMainDeFinition(query);
    return kind === "OperationDeFinition" && operation === "subscription";
  },wsLink,httpLink
);

const link = ApolloLink.from([errLink,authLink,splittedLink]);

const client = new ApolloClient({
  cache: new InMemoryCache(),link,});

export default client;

我像上面的代码一样创建了 authLink、errLink、httpLink 和 wsLink。并使用 split 函数将 httpLink 和 wsLink 结合起来,它可以毫无问题地运行查询,但是当我尝试运行订阅挂钩时,它会抛出以下错误消息。

Could not find "client" in the context or passed in as an option. Wrap the root component in an <ApolloProvider>,or pass an ApolloClient instance in via options.  

我也将客户端作为道具传递

ReactDOM.render(
  <browserRouter>
    <ApolloProvider client={client}>
      <SnackbarProvider maxSnack={5}>
        <SnackbarUtilsConfigurator />
        <Route path="/" component={App} />
      </SnackbarProvider>
    </ApolloProvider>
  </browserRouter>,document.getElementById("root")
);

如何解决这个问题?

解决方法

能否请您分享一下您如何使用 ApolloProvider?看起来你错过了这个:

import React from 'react';
import { render } from 'react-dom';
import { ApolloProvider } from '@apollo/client/react';

const client = new ApolloClient({ uri,cache });

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

render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,document.getElementById('root'),);

确保您将 client 作为道具传递给 ApolloProvider