我创建了ApolloCustomProvider
,因为我想使用我的addNotification
中的AppContext
函数来处理graphQL错误。
问题是此自定义提供程序在查询或更改API时似乎可以工作,但是errorLink
和addNotification
之类的功能不起作用。 console.log()
功能的console.log()
也不会打印任何内容。
但是当我将所有内容从request
放入标准TypeScript文件(.ts-不是React Component),然后像这样使用它时:
ApolloCustomProvider
一切正常。所有import { ApolloProvider } from '@apollo/react-hooks'
import client from 'api/client'
...
<ApolloProvider client={client}>
<App />
</ApolloProvider>
的打印等。当然,没有console.log
的addNotification
。允许使用AppContext
是我创建自定义提供程序的原因。
文件:
AppContext
import React, { ReactElement } from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import AppContextProvider from 'contexts/AppContext'
import ApolloCustomProvider from 'components/ApolloCustomProvider'
const AppContainer = (): ReactElement => (
<AppContextProvider>
<ApolloCustomProvider>
<App />
</ApolloCustomProvider>
</AppContextProvider>
)
ReactDOM.render(<AppContainer />, document.getElementById('root'))
[我正在尝试回答您的问题我所做的更改是:1.将您的功能组件更改为类组件,原因是当您添加通知时,整个组件将不会重新呈现。但是,如果您使用功能组件并在onError上导致垃圾邮件通知,它将重新呈现。2.更改apolloLink的顺序。这是源import React, { useContext, useEffect } from 'react'
import { ApolloProvider } from '@apollo/react-hooks'
import { ApolloClient, DefaultOptions } from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloLink, Observable, Operation, NextLink } from 'apollo-link'
import { createUploadLink } from 'apollo-upload-client'
import { onError } from 'apollo-link-error'
import { AppContext } from 'contexts/AppContext'
import { Subscription } from 'apollo-client/util/Observable'
import { NotifierType } from 'components/Notifier'
import i18n from 'i18n'
const ApolloCustomProvider: React.FC = ({ children }) => {
const { addNotification } = useContext(AppContext)
useEffect(() => {
console.log('ApolloCustomProvider render')
})
const request = (operation: Operation): void => {
console.log('ApolloCustomProvider request')
const token = localStorage.getItem('at')
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : '',
},
})
}
const requestLink = new ApolloLink(
(operation: Operation, nextLink: NextLink) =>
new Observable(observer => {
console.log('gql requestLink observer')
let handle: Subscription
Promise.resolve(operation)
.then((o: Operation): void => void request(o))
.then(() => {
handle = nextLink(operation).subscribe({
next: observer.next.bind(observer),
error: observer.error.bind(observer),
complete: observer.complete.bind(observer),
})
})
.catch(observer.error.bind(observer))
return (): void => {
if (handle) handle.unsubscribe()
}
})
)
const errorLink: ApolloLink = onError(({ graphQLErrors, networkError }): void => {
console.log('ApolloCustomProvider errors', graphQLErrors, networkError)
if (graphQLErrors)
addNotification(
NotifierType.ERROR,
graphQLErrors.map(({ message }) => message)
)
if (networkError)
addNotification(NotifierType.ERROR, [
`${i18n.t('notification.networkError')}: ${networkError.message}`,
])
})
const uploadLink: ApolloLink = createUploadLink({ uri: process.env.REACT_APP_CORE_URI })
const defaultOptions: DefaultOptions = {
watchQuery: {
fetchPolicy: 'no-cache',
},
query: {
fetchPolicy: 'no-cache',
},
}
const client = new ApolloClient({
link: ApolloLink.from([requestLink, errorLink, uploadLink]),
cache: new InMemoryCache(),
defaultOptions,
})
return <ApolloProvider client={client}>{children}</ApolloProvider>
}
export default ApolloCustomProvider
。作者说https://github.com/apollographql/apollo-link/issues/133在LogLink
之前先运行。他将httpLink
放在LogLink
之后。