我需要实时获取一些数据。所以我决定使用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")
);
如何解决这个问题?
答案 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