Graphql 如何在中继中动态改变网络层

Graphql 如何在中继中动态改变网络层,graphql,relay,Graphql,Relay,我知道中继可以在引导时注入网络层,如下所示: Relay.injectNetworkLayer( new Relay.DefaultNetworkLayer('http://example.com/graphql', { headers: { Authorization: 'Basic SSdsbCBmaW5kIHNvbWV0aGluZyB0byBwdXQgaGVyZQ==', }, }) ); 但是如果我以后需要告诉你标题是什么(比如登录后)?好问题。我想

我知道中继可以在引导时注入网络层,如下所示:

Relay.injectNetworkLayer(
  new Relay.DefaultNetworkLayer('http://example.com/graphql', {
    headers: {
      Authorization: 'Basic SSdsbCBmaW5kIHNvbWV0aGluZyB0byBwdXQgaGVyZQ==',
    },
  })
);

但是如果我以后需要告诉你标题是什么(比如登录后)?

好问题。我想您正在基本组件文件中设置网络层。您可以创建一个包装Relay.injectNetworkLayer调用的函数,在需要时更新Auth头

加载应用程序时,您可以执行以下操作:

export function setNetworkLayer() {
  return new Promise((resolve, reject) => {

      var options = {};
      if (localStorage.authToken) {
        options.headers = {
          Authorization: 'Basic ' + localStorage.authToken
        }
      }
      else {
        options.headers = {};
      }
      Relay.injectNetworkLayer(
        new Relay.DefaultNetworkLayer('http://example.com/graphql', options)
      );
      resolve(options);
    });
  })
}
loginUser().then((res) => {
    localStorage.authToken = res.token;
    setNetworkLayer();
    return;
})
如果你想更新网络层,你可以这样做:

export function setNetworkLayer() {
  return new Promise((resolve, reject) => {

      var options = {};
      if (localStorage.authToken) {
        options.headers = {
          Authorization: 'Basic ' + localStorage.authToken
        }
      }
      else {
        options.headers = {};
      }
      Relay.injectNetworkLayer(
        new Relay.DefaultNetworkLayer('http://example.com/graphql', options)
      );
      resolve(options);
    });
  })
}
loginUser().then((res) => {
    localStorage.authToken = res.token;
    setNetworkLayer();
    return;
})

我在github relay repo中提出了这个问题,他们建议我使用这个库来解决这个问题。我相信这将是解决这个问题的最佳选择

我发现了一个简单的窍门。您可以传入headers对象并更新其指针值

const headers = {
    Authorization: '',
};

Relay.injectNetworkLayer(
  new Relay.DefaultNetworkLayer('http://example.com/graphql', {
    headers: headers,
  })
);

// To update the authorization, set the field.

headers.Authorization = 'Basic SSdsbCBmaW5kIHNvbWV0aGluZyB0byBwdXQgaGVyZQ=='

这意味着延迟注入网络层。但是,如果我想在使用有效令牌登录setup networkLayer后,首先使用空标题(匿名)设置networkLayer,该怎么办?您可以在应用程序的第一个render()函数中调用setNetworkLayer。如果在localStorage中未检测到authToken,则会将options变量设置为空对象,并将DefaultNetworkLayer设置为空标题。无论何时需要重置网络层,都可以覆盖localStorage.authToken变量并再次调用setNetworkLayer()。我尝试调用injectNetworkLayer两次,得到的警告是:“RelayNetworkLayer:已收到对injectImplementation()的调用,但已注入层。”。此外,新呼叫未生效,第一个呼叫也未停止工作。这似乎是一个警告,将在下一版本中解决:。现在,当需要从localStorage加载具有网络层身份验证令牌的应用程序时,请尝试重新呈现DOM.render(),如下所示:实际上,上面的问题是:injectNetworkLayer将导致警告,即使是在应用程序中的第一次。因此,0.9版本引入了injectDefaultNetworkLayer,它仅在内部用于将默认层设置为“/graphql”。然而,我们现在面临的问题是我们不能在应用程序中调用injectNetworkLayer两次。非常方便!如何更新另一个文件中的值?您可以导出中继DefaultNetworkLayer中使用的
变量,并在任何位置设置授权。它是
headers.Authorization=
部分,除非您在不同的文件中这样做。