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

时间:2021-04-23 03:10:04

标签: apollo-client react-apollo graphql-subscriptions

我需要实时获取一些数据。所以我决定使用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")
);

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

能否请您分享一下您如何使用 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