用于访问内部React Context的自定义ApolloProvider

问题描述 投票:0回答:1

我创建了ApolloCustomProvider,因为我想使用我的addNotification中的AppContext函数来处理graphQL错误。

问题是此自定义提供程序在查询或更改API时似乎可以工作,但是errorLinkaddNotification之类的功能不起作用。 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.logaddNotification。允许使用AppContext是我创建自定义提供程序的原因。

文件:

  • index.ts
AppContext
  • ApolloCustomProvider.tsx
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'))
reactjs apollo react-apollo apollo-client react-apollo-hooks
1个回答
0
投票

[我正在尝试回答您的问题我所做的更改是: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/133LogLink之前先运行。他将httpLink放在LogLink之后。

© www.soinside.com 2019 - 2024. All rights reserved.