初始化后更新ApolloClient标头

时间:2019-04-29 11:57:11

标签: reactjs graphql apollo react-apollo

我的应用包裹着<Apollo />组件,该组件实际上是在初始化客户端。

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

进一步,用户可以执行某些操作,这需要我为apollo客户端设置一些以前没有的新标头。最初,我想为此使用react上下文来传递设置的新标头并在<Apollo />中使用它们,但是不确定这是否是正确的方法。

浏览文档后,似乎只能在初始化时设置阿波罗标题吗?

2 个答案:

答案 0 :(得分:1)

通常不希望将标头直接传递到您的Apollo客户端实例,而是要使用apollo-link-context。您可以将实际的标头值存储在内存,LocalStorage或对您的应用有意义的任何内容中。然后使用链接将其注入每个请求中,然后再发送:

const headerLink = setContext((request, previousContext) => ({
  headers: {
    // Make sure you include any existing headers!
    ...previousContext.headers,
    authorization: localStorage.getItem('authHeader')
  },
}));

const client = new ApolloClient({
  link: headerLink.concat(httpLink),
  cache: new InMemoryCache()
});

setContext可以是异步的。传递给它的函数应该返回一个对象,该对象具有您想要更改的任何上下文字段,或者返回一个将解析为一个的Promise:

const headerLink = setContext(async (request, previousContext) => {
  const authorization = await someAsyncCall()
  return {
    headers: {
      ...previousContext.headers,
      authorization,
    },
  }
});

您可以查看the docs以获得更多示例。

答案 1 :(得分:0)

Daniel Rearden是对的。但是,在Apollo 3中,有一些小的更改,我发现在文档中尚未很好地系统化这些更改。所以也许也会有所帮助。

import React from 'react';
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';

function App() {

  const link = new HttpLink({ uri: process.env.REACT_APP_GRAPHQL_URI });

  const setAuthorizationLink = setContext((request, previousContext) => ({
    headers: {
      ...previousContext.headers,
      authorization: `Bearer ${ localStorage.getItem('auth_token') }`
    }
  }));

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

  return (
    <ApolloProvider client={client}>
      ...
    </ApolloProvider>
  );
}

export default App;

Migrating to Apollo Client 3.0 (docs)